Bug 1889091 - Part 6: Remove "scratch" register parameter from emitPushArguments...
[gecko.git] / dom / storage / StorageIPC.h
blob41d9d88319fea66c57b008fc0813755a902435ed
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_StorageIPC_h
8 #define mozilla_dom_StorageIPC_h
10 #include "LocalStorageCache.h"
11 #include "StorageDBThread.h"
12 #include "StorageObserver.h"
14 #include "mozilla/Mutex.h"
15 #include "mozilla/UniquePtr.h"
16 #include "mozilla/dom/FlippedOnce.h"
17 #include "mozilla/dom/PBackgroundLocalStorageCacheChild.h"
18 #include "mozilla/dom/PBackgroundLocalStorageCacheParent.h"
19 #include "mozilla/dom/PBackgroundSessionStorageCacheChild.h"
20 #include "mozilla/dom/PBackgroundSessionStorageCacheParent.h"
21 #include "mozilla/dom/PBackgroundSessionStorageManagerChild.h"
22 #include "mozilla/dom/PBackgroundSessionStorageManagerParent.h"
23 #include "mozilla/dom/PBackgroundStorageChild.h"
24 #include "mozilla/dom/PBackgroundStorageParent.h"
25 #include "mozilla/dom/PSessionStorageObserverChild.h"
26 #include "mozilla/dom/PSessionStorageObserverParent.h"
27 #include "nsTHashSet.h"
29 namespace mozilla {
31 class OriginAttributesPattern;
33 namespace ipc {
35 class BackgroundChildImpl;
36 class PrincipalInfo;
38 } // namespace ipc
40 namespace dom {
42 class LocalStorageManager;
43 class PBackgroundStorageParent;
44 class PSessionStorageObserverParent;
45 class SessionStorageCache;
46 class SessionStorageCacheParent;
47 class SessionStorageManager;
48 class SessionStorageManagerParent;
49 class BackgroundSessionStorageManager;
50 class SessionStorageObserver;
52 class LocalStorageCacheChild final : public PBackgroundLocalStorageCacheChild {
53 friend class mozilla::ipc::BackgroundChildImpl;
54 friend class LocalStorageCache;
55 friend class LocalStorageManager;
57 // LocalStorageCache effectively owns this instance, although IPC handles its
58 // allocation/deallocation. When the LocalStorageCache destructor runs, it
59 // will invoke SendDeleteMeInternal() which will trigger both instances to
60 // drop their mutual references and cause IPC to destroy the actor after the
61 // DeleteMe round-trip.
62 LocalStorageCache* MOZ_NON_OWNING_REF mCache;
64 NS_DECL_OWNINGTHREAD
66 public:
67 void AssertIsOnOwningThread() const {
68 NS_ASSERT_OWNINGTHREAD(LocalStorageCacheChild);
71 private:
72 // Only created by LocalStorageManager.
73 explicit LocalStorageCacheChild(LocalStorageCache* aCache);
75 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
76 ~LocalStorageCacheChild();
78 // Only called by LocalStorageCache.
79 void SendDeleteMeInternal();
81 // IPDL methods are only called by IPDL.
82 void ActorDestroy(ActorDestroyReason aWhy) override;
84 mozilla::ipc::IPCResult RecvObserve(const PrincipalInfo& aPrincipalInfo,
85 const PrincipalInfo& aCachePrincipalInfo,
86 const uint32_t& aPrivateBrowsingId,
87 const nsAString& aDocumentURI,
88 const nsAString& aKey,
89 const nsAString& aOldValue,
90 const nsAString& aNewValue) override;
93 // Child side of the IPC protocol, exposes as DB interface but
94 // is responsible to send all requests to the parent process
95 // and expects asynchronous answers. Those are then transparently
96 // forwarded back to consumers on the child process.
97 class StorageDBChild final : public PBackgroundStorageChild {
98 class ShutdownObserver;
100 virtual ~StorageDBChild();
102 public:
103 StorageDBChild(LocalStorageManager* aManager, uint32_t aPrivateBrowsingId);
105 static StorageDBChild* Get(uint32_t aPrivateBrowsingId);
107 static StorageDBChild* GetOrCreate(uint32_t aPrivateBrowsingId);
109 NS_INLINE_DECL_REFCOUNTING(StorageDBChild);
111 void AddIPDLReference();
112 void ReleaseIPDLReference();
114 virtual nsresult Init();
115 virtual nsresult Shutdown();
117 virtual void AsyncPreload(LocalStorageCacheBridge* aCache,
118 bool aPriority = false);
119 virtual void AsyncGetUsage(StorageUsageBridge* aUsage);
121 virtual void SyncPreload(LocalStorageCacheBridge* aCache,
122 bool aForceSync = false);
124 virtual nsresult AsyncAddItem(LocalStorageCacheBridge* aCache,
125 const nsAString& aKey, const nsAString& aValue);
126 virtual nsresult AsyncUpdateItem(LocalStorageCacheBridge* aCache,
127 const nsAString& aKey,
128 const nsAString& aValue);
129 virtual nsresult AsyncRemoveItem(LocalStorageCacheBridge* aCache,
130 const nsAString& aKey);
131 virtual nsresult AsyncClear(LocalStorageCacheBridge* aCache);
133 virtual void AsyncClearAll() {
134 if (mOriginsHavingData) {
135 mOriginsHavingData->Clear(); /* NO-OP on the child process otherwise */
139 virtual void AsyncClearMatchingOrigin(const nsACString& aOriginNoSuffix) {
140 MOZ_CRASH("Shouldn't be called!");
143 virtual void AsyncClearMatchingOriginAttributes(
144 const OriginAttributesPattern& aPattern) {
145 MOZ_CRASH("Shouldn't be called!");
148 virtual void AsyncFlush() { MOZ_CRASH("Shouldn't be called!"); }
150 virtual bool ShouldPreloadOrigin(const nsACString& aOriginNoSuffix);
152 private:
153 mozilla::ipc::IPCResult RecvObserve(const nsACString& aTopic,
154 const nsAString& aOriginAttributesPattern,
155 const nsACString& aOriginScope) override;
156 mozilla::ipc::IPCResult RecvLoadItem(const nsACString& aOriginSuffix,
157 const nsACString& aOriginNoSuffix,
158 const nsAString& aKey,
159 const nsAString& aValue) override;
160 mozilla::ipc::IPCResult RecvLoadDone(const nsACString& aOriginSuffix,
161 const nsACString& aOriginNoSuffix,
162 const nsresult& aRv) override;
163 mozilla::ipc::IPCResult RecvOriginsHavingData(
164 nsTArray<nsCString>&& aOrigins) override;
165 mozilla::ipc::IPCResult RecvLoadUsage(const nsACString& aOriginNoSuffix,
166 const int64_t& aUsage) override;
167 mozilla::ipc::IPCResult RecvError(const nsresult& aRv) override;
169 nsTHashSet<nsCString>& OriginsHavingData();
171 // Held to get caches to forward answers to.
172 RefPtr<LocalStorageManager> mManager;
174 // Origins having data hash, for optimization purposes only
175 UniquePtr<nsTHashSet<nsCString>> mOriginsHavingData;
177 // List of caches waiting for preload. This ensures the contract that
178 // AsyncPreload call references the cache for time of the preload.
179 nsTHashSet<RefPtr<LocalStorageCacheBridge>> mLoadingCaches;
181 // Expected to be only 0 or 1.
182 const uint32_t mPrivateBrowsingId;
184 // Status of the remote database
185 nsresult mStatus;
187 bool mIPCOpen;
190 class SessionStorageObserverChild final : public PSessionStorageObserverChild {
191 friend class SessionStorageManager;
192 friend class SessionStorageObserver;
194 // SessionStorageObserver effectively owns this instance, although IPC handles
195 // its allocation/deallocation. When the SessionStorageObserver destructor
196 // runs, it will invoke SendDeleteMeInternal() which will trigger both
197 // instances to drop their mutual references and cause IPC to destroy the
198 // actor after the DeleteMe round-trip.
199 SessionStorageObserver* MOZ_NON_OWNING_REF mObserver;
201 NS_DECL_OWNINGTHREAD
203 public:
204 void AssertIsOnOwningThread() const {
205 NS_ASSERT_OWNINGTHREAD(LocalStorageCacheChild);
208 private:
209 // Only created by SessionStorageManager.
210 explicit SessionStorageObserverChild(SessionStorageObserver* aObserver);
212 ~SessionStorageObserverChild();
214 // Only called by SessionStorageObserver.
215 void SendDeleteMeInternal();
217 // IPDL methods are only called by IPDL.
218 void ActorDestroy(ActorDestroyReason aWhy) override;
220 mozilla::ipc::IPCResult RecvObserve(const nsACString& aTopic,
221 const nsAString& aOriginAttributesPattern,
222 const nsACString& aOriginScope) override;
225 class SessionStorageCacheChild final
226 : public PBackgroundSessionStorageCacheChild {
227 friend class PBackgroundSessionStorageCacheChild;
228 friend class SessionStorageCache;
229 friend class SessionStorageManager;
230 friend class mozilla::ipc::BackgroundChildImpl;
232 // SessionStorageManagerChild effectively owns this instance, although IPC
233 // handles its allocation/deallocation. When the SessionStorageManager
234 // destructor runs, it will invoke SendDeleteMeInternal() which will trigger
235 // both instances to drop their mutual references and cause IPC to destroy the
236 // actor after the DeleteMe round-trip.
237 SessionStorageCache* MOZ_NON_OWNING_REF mCache;
239 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::SessionStorageCacheChild, override)
241 public:
242 void AssertIsOnOwningThread() const {
243 NS_ASSERT_OWNINGTHREAD(SesionStoragManagerChild);
246 private:
247 // Only created by SessionStorageManager.
248 explicit SessionStorageCacheChild(SessionStorageCache* aCache);
250 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
251 ~SessionStorageCacheChild();
253 // Only called by SessionStorageCache.
254 void SendDeleteMeInternal();
256 // IPDL methods are only called by IPDL.
257 void ActorDestroy(ActorDestroyReason aWhy) override;
260 class SessionStorageManagerChild final
261 : public PBackgroundSessionStorageManagerChild {
262 friend class PBackgroundSessionStorageManagerChild;
263 friend class SessionStorage;
264 friend class SessionStorageManager;
265 friend class mozilla::ipc::BackgroundChildImpl;
267 // SessionStorageManager effectively owns this instance, although IPC handles
268 // its allocation/deallocation. When the SessionStorageManager destructor
269 // runs, it will invoke SendDeleteMeInternal() which will trigger both
270 // instances to drop their mutual references and cause IPC to destroy the
271 // actor after the DeleteMe round-trip.
272 SessionStorageManager* MOZ_NON_OWNING_REF mSSManager;
274 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::SessionStorageManagerChild, override)
276 public:
277 void AssertIsOnOwningThread() const {
278 NS_ASSERT_OWNINGTHREAD(SesionStoragManagerChild);
281 private:
282 // Only created by SessionStorage.
283 explicit SessionStorageManagerChild(SessionStorageManager* aSSManager);
285 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
286 ~SessionStorageManagerChild();
288 // Only called by SessionStorageManager.
289 void SendDeleteMeInternal();
291 // IPDL methods are only called by IPDL.
292 void ActorDestroy(ActorDestroyReason aWhy) override;
294 mozilla::ipc::IPCResult RecvClearStoragesForOrigin(
295 const nsACString& aOriginAttrs, const nsACString& aOriginKey) override;
298 class LocalStorageCacheParent final
299 : public PBackgroundLocalStorageCacheParent {
300 const PrincipalInfo mPrincipalInfo;
301 const nsCString mOriginKey;
302 uint32_t mPrivateBrowsingId;
303 bool mActorDestroyed;
305 public:
306 // Created in AllocPBackgroundLocalStorageCacheParent.
307 LocalStorageCacheParent(const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
308 const nsACString& aOriginKey,
309 uint32_t aPrivateBrowsingId);
311 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::LocalStorageCacheParent)
313 const PrincipalInfo& PrincipalInfo() const { return mPrincipalInfo; }
315 private:
316 // Reference counted.
317 ~LocalStorageCacheParent();
319 // IPDL methods are only called by IPDL.
320 void ActorDestroy(ActorDestroyReason aWhy) override;
322 mozilla::ipc::IPCResult RecvDeleteMe() override;
324 mozilla::ipc::IPCResult RecvNotify(const nsAString& aDocumentURI,
325 const nsAString& aKey,
326 const nsAString& aOldValue,
327 const nsAString& aNewValue) override;
330 // Receives async requests from child processes and is responsible
331 // to send back responses from the DB thread. Exposes as a fake
332 // LocalStorageCache consumer.
333 // Also responsible for forwardning all chrome operation notifications
334 // such as cookie cleaning etc to the child process.
335 class StorageDBParent final : public PBackgroundStorageParent {
336 class ObserverSink;
338 virtual ~StorageDBParent();
340 public:
341 StorageDBParent(const nsAString& aProfilePath, uint32_t aPrivateBrowsingId);
343 void Init();
345 NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
346 NS_IMETHOD_(MozExternalRefCountType) Release(void);
348 void AddIPDLReference();
349 void ReleaseIPDLReference();
351 bool IPCOpen() { return mIPCOpen; }
353 public:
354 // Fake cache class receiving async callbacks from DB thread, sending
355 // them back to appropriate cache object on the child process.
356 class CacheParentBridge : public LocalStorageCacheBridge {
357 public:
358 CacheParentBridge(StorageDBParent* aParentDB,
359 const nsACString& aOriginSuffix,
360 const nsACString& aOriginNoSuffix)
361 : mOwningEventTarget(GetCurrentSerialEventTarget()),
362 mParent(aParentDB),
363 mOriginSuffix(aOriginSuffix),
364 mOriginNoSuffix(aOriginNoSuffix),
365 mLoaded(false),
366 mLoadedCount(0) {}
367 virtual ~CacheParentBridge() = default;
369 // LocalStorageCacheBridge
370 virtual const nsCString Origin() const override;
371 virtual const nsCString& OriginNoSuffix() const override {
372 return mOriginNoSuffix;
374 virtual const nsCString& OriginSuffix() const override {
375 return mOriginSuffix;
377 virtual bool Loaded() override { return mLoaded; }
378 virtual uint32_t LoadedCount() override { return mLoadedCount; }
380 virtual bool LoadItem(const nsAString& aKey,
381 const nsAString& aValue) override;
382 virtual void LoadDone(nsresult aRv) override;
383 virtual void LoadWait() override;
385 NS_IMETHOD_(void)
386 Release(void) override;
388 private:
389 void Destroy();
391 nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
392 RefPtr<StorageDBParent> mParent;
393 nsCString mOriginSuffix, mOriginNoSuffix;
394 bool mLoaded;
395 uint32_t mLoadedCount;
398 // Fake usage class receiving async callbacks from DB thread
399 class UsageParentBridge : public StorageUsageBridge {
400 public:
401 UsageParentBridge(StorageDBParent* aParentDB,
402 const nsACString& aOriginScope)
403 : mOwningEventTarget(GetCurrentSerialEventTarget()),
404 mParent(aParentDB),
405 mOriginScope(aOriginScope) {}
406 virtual ~UsageParentBridge() = default;
408 // StorageUsageBridge
409 virtual const nsCString& OriginScope() override { return mOriginScope; }
410 virtual void LoadUsage(const int64_t usage) override;
412 NS_IMETHOD_(MozExternalRefCountType)
413 Release(void) override;
415 private:
416 void Destroy();
418 nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
419 RefPtr<StorageDBParent> mParent;
420 nsCString mOriginScope;
423 private:
424 // IPC
425 virtual void ActorDestroy(ActorDestroyReason aWhy) override;
426 mozilla::ipc::IPCResult RecvDeleteMe() override;
428 mozilla::ipc::IPCResult RecvAsyncPreload(const nsACString& aOriginSuffix,
429 const nsACString& aOriginNoSuffix,
430 const bool& aPriority) override;
431 mozilla::ipc::IPCResult RecvPreload(const nsACString& aOriginSuffix,
432 const nsACString& aOriginNoSuffix,
433 const uint32_t& aAlreadyLoadedCount,
434 nsTArray<nsString>* aKeys,
435 nsTArray<nsString>* aValues,
436 nsresult* aRv) override;
437 mozilla::ipc::IPCResult RecvAsyncGetUsage(
438 const nsACString& aOriginNoSuffix) override;
439 mozilla::ipc::IPCResult RecvAsyncAddItem(const nsACString& aOriginSuffix,
440 const nsACString& aOriginNoSuffix,
441 const nsAString& aKey,
442 const nsAString& aValue) override;
443 mozilla::ipc::IPCResult RecvAsyncUpdateItem(const nsACString& aOriginSuffix,
444 const nsACString& aOriginNoSuffix,
445 const nsAString& aKey,
446 const nsAString& aValue) override;
447 mozilla::ipc::IPCResult RecvAsyncRemoveItem(const nsACString& aOriginSuffix,
448 const nsACString& aOriginNoSuffix,
449 const nsAString& aKey) override;
450 mozilla::ipc::IPCResult RecvAsyncClear(
451 const nsACString& aOriginSuffix,
452 const nsACString& aOriginNoSuffix) override;
453 mozilla::ipc::IPCResult RecvAsyncFlush() override;
455 mozilla::ipc::IPCResult RecvStartup() override;
456 mozilla::ipc::IPCResult RecvClearAll() override;
457 mozilla::ipc::IPCResult RecvClearMatchingOrigin(
458 const nsACString& aOriginNoSuffix) override;
459 mozilla::ipc::IPCResult RecvClearMatchingOriginAttributes(
460 const OriginAttributesPattern& aPattern) override;
462 void Observe(const nsACString& aTopic, const nsAString& aOriginAttrPattern,
463 const nsACString& aOriginScope);
465 private:
466 CacheParentBridge* NewCache(const nsACString& aOriginSuffix,
467 const nsACString& aOriginNoSuffix);
469 RefPtr<ObserverSink> mObserverSink;
471 // A hack to deal with deadlock between the parent process main thread and
472 // background thread when invoking StorageDBThread::GetOrCreate because it
473 // cannot safely perform a synchronous dispatch back to the main thread
474 // (because we are already synchronously doing things on the stack).
475 // Populated for the same process actors, empty for other process actors.
476 nsString mProfilePath;
478 // Expected to be only 0 or 1.
479 const uint32_t mPrivateBrowsingId;
481 ThreadSafeAutoRefCnt mRefCnt;
482 NS_DECL_OWNINGTHREAD
484 // True when IPC channel is open and Send*() methods are OK to use.
485 bool mIPCOpen;
488 class SessionStorageObserverParent final : public PSessionStorageObserverParent,
489 public StorageObserverSink {
490 bool mActorDestroyed;
492 public:
493 // Created in AllocPSessionStorageObserverParent.
494 SessionStorageObserverParent();
496 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::SessionStorageObserverParent)
498 private:
499 // Reference counted.
500 ~SessionStorageObserverParent();
502 // IPDL methods are only called by IPDL.
503 void ActorDestroy(ActorDestroyReason aWhy) override;
505 mozilla::ipc::IPCResult RecvDeleteMe() override;
507 // StorageObserverSink
508 nsresult Observe(const char* aTopic, const nsAString& aOriginAttrPattern,
509 const nsACString& aOriginScope) override;
512 class SessionStorageCacheParent final
513 : public PBackgroundSessionStorageCacheParent {
514 friend class PBackgroundSessionStorageCacheParent;
515 const PrincipalInfo mPrincipalInfo;
516 const nsCString mOriginKey;
518 RefPtr<SessionStorageManagerParent> mManagerActor;
519 FlippedOnce<false> mLoadReceived;
521 public:
522 SessionStorageCacheParent(const PrincipalInfo& aPrincipalInfo,
523 const nsACString& aOriginKey,
524 SessionStorageManagerParent* aActor);
526 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::SessionStorageCacheParent, override)
528 const PrincipalInfo& PrincipalInfo() const { return mPrincipalInfo; }
529 const nsACString& OriginKey() const { return mOriginKey; }
531 private:
532 ~SessionStorageCacheParent();
534 // IPDL methods are only called by IPDL.
535 void ActorDestroy(ActorDestroyReason aWhy) override;
537 mozilla::ipc::IPCResult RecvLoad(nsTArray<SSSetItemInfo>* aData) override;
539 mozilla::ipc::IPCResult RecvCheckpoint(
540 nsTArray<SSWriteInfo>&& aWriteInfos) override;
542 mozilla::ipc::IPCResult RecvDeleteMe() override;
545 class SessionStorageManagerParent final
546 : public PBackgroundSessionStorageManagerParent {
547 friend class PBackgroundSessionStorageManagerParent;
549 RefPtr<BackgroundSessionStorageManager> mBackgroundManager;
551 public:
552 explicit SessionStorageManagerParent(uint64_t aTopContextId);
554 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::SessionStorageManagerParent,
555 override)
557 already_AddRefed<PBackgroundSessionStorageCacheParent>
558 AllocPBackgroundSessionStorageCacheParent(
559 const PrincipalInfo& aPrincipalInfo,
560 const nsACString& aOriginKey) override;
562 BackgroundSessionStorageManager* GetManager() const;
564 mozilla::ipc::IPCResult RecvClearStorages(
565 const OriginAttributesPattern& aPattern,
566 const nsACString& aOriginScope) override;
568 private:
569 ~SessionStorageManagerParent();
571 // IPDL methods are only called by IPDL.
572 void ActorDestroy(ActorDestroyReason aWhy) override;
574 mozilla::ipc::IPCResult RecvDeleteMe() override;
577 PBackgroundLocalStorageCacheParent* AllocPBackgroundLocalStorageCacheParent(
578 const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
579 const nsACString& aOriginKey, const uint32_t& aPrivateBrowsingId);
581 mozilla::ipc::IPCResult RecvPBackgroundLocalStorageCacheConstructor(
582 mozilla::ipc::PBackgroundParent* aBackgroundActor,
583 PBackgroundLocalStorageCacheParent* aActor,
584 const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
585 const nsACString& aOriginKey, const uint32_t& aPrivateBrowsingId);
587 bool DeallocPBackgroundLocalStorageCacheParent(
588 PBackgroundLocalStorageCacheParent* aActor);
590 PBackgroundStorageParent* AllocPBackgroundStorageParent(
591 const nsAString& aProfilePath, const uint32_t& aPrivateBrowsingId);
593 mozilla::ipc::IPCResult RecvPBackgroundStorageConstructor(
594 PBackgroundStorageParent* aActor, const nsAString& aProfilePath,
595 const uint32_t& aPrivateBrowsingId);
597 bool DeallocPBackgroundStorageParent(PBackgroundStorageParent* aActor);
599 PSessionStorageObserverParent* AllocPSessionStorageObserverParent();
601 bool RecvPSessionStorageObserverConstructor(
602 PSessionStorageObserverParent* aActor);
604 bool DeallocPSessionStorageObserverParent(
605 PSessionStorageObserverParent* aActor);
607 already_AddRefed<PBackgroundSessionStorageCacheParent>
608 AllocPBackgroundSessionStorageCacheParent(
609 const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
610 const nsACString& aOriginKey);
612 already_AddRefed<PBackgroundSessionStorageManagerParent>
613 AllocPBackgroundSessionStorageManagerParent(const uint64_t& aTopContextId);
614 } // namespace dom
615 } // namespace mozilla
617 #endif // mozilla_dom_StorageIPC_h