Backed out 22 changesets (bug 1839396) for causing build bustages on js/Printer.h...
[gecko.git] / dom / indexedDB / ActorsChild.h
blob693e69cbcac32b3129bd8779eca04b1a527492d1
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_indexeddb_actorschild_h__
8 #define mozilla_dom_indexeddb_actorschild_h__
10 #include "js/RootingAPI.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/dom/IDBCursorType.h"
13 #include "mozilla/dom/IDBTransaction.h"
14 #include "mozilla/dom/indexedDB/PBackgroundIDBCursorChild.h"
15 #include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseChild.h"
16 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
17 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryRequestChild.h"
18 #include "mozilla/dom/indexedDB/PBackgroundIDBRequestChild.h"
19 #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
20 #include "mozilla/dom/indexedDB/PBackgroundIDBTransactionChild.h"
21 #include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionChild.h"
22 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
23 #include "mozilla/InitializedOnce.h"
24 #include "mozilla/UniquePtr.h"
25 #include "nsCOMPtr.h"
26 #include "nsTArray.h"
28 class nsIEventTarget;
29 struct nsID;
31 namespace mozilla {
32 namespace ipc {
34 class BackgroundChildImpl;
36 } // namespace ipc
38 namespace dom {
40 class IDBCursor;
41 class IDBDatabase;
42 class IDBFactory;
43 class IDBOpenDBRequest;
44 class IDBRequest;
45 class IndexedDatabaseManager;
47 namespace indexedDB {
49 class Key;
50 class PermissionRequestChild;
51 class PermissionRequestParent;
52 class SerializedStructuredCloneReadInfo;
53 struct CloneInfo;
55 } // namespace indexedDB
56 } // namespace dom
57 } // namespace mozilla
59 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(mozilla::dom::indexedDB::CloneInfo)
61 namespace mozilla::dom::indexedDB {
63 class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
64 friend class mozilla::ipc::BackgroundChildImpl;
65 friend IDBFactory;
67 // TODO: This long-lived raw pointer is very suspicious, in particular as it
68 // is used in BackgroundDatabaseChild::EnsureDOMObject to reacquire a strong
69 // reference. What ensures it is kept alive, and why can't we store a strong
70 // reference here?
71 IDBFactory* mFactory;
73 public:
74 NS_INLINE_DECL_REFCOUNTING(BackgroundFactoryChild, override)
76 void AssertIsOnOwningThread() const {
77 NS_ASSERT_OWNINGTHREAD(BackgroundFactoryChild);
80 IDBFactory& GetDOMObject() const {
81 AssertIsOnOwningThread();
82 MOZ_ASSERT(mFactory);
83 return *mFactory;
86 bool SendDeleteMe() = delete;
88 private:
89 // Only created by IDBFactory.
90 explicit BackgroundFactoryChild(IDBFactory& aFactory);
92 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
93 ~BackgroundFactoryChild();
95 void SendDeleteMeInternal();
97 public:
98 // IPDL methods are only called by IPDL.
99 void ActorDestroy(ActorDestroyReason aWhy) override;
101 PBackgroundIDBFactoryRequestChild* AllocPBackgroundIDBFactoryRequestChild(
102 const FactoryRequestParams& aParams);
104 bool DeallocPBackgroundIDBFactoryRequestChild(
105 PBackgroundIDBFactoryRequestChild* aActor);
107 PBackgroundIDBDatabaseChild* AllocPBackgroundIDBDatabaseChild(
108 const DatabaseSpec& aSpec,
109 PBackgroundIDBFactoryRequestChild* aRequest) const;
111 bool DeallocPBackgroundIDBDatabaseChild(PBackgroundIDBDatabaseChild* aActor);
113 mozilla::ipc::IPCResult RecvPBackgroundIDBDatabaseConstructor(
114 PBackgroundIDBDatabaseChild* aActor, const DatabaseSpec& aSpec,
115 NotNull<PBackgroundIDBFactoryRequestChild*> aRequest) override;
118 class BackgroundDatabaseChild;
120 class BackgroundRequestChildBase {
121 protected:
122 const NotNull<RefPtr<IDBRequest>> mRequest;
124 public:
125 void AssertIsOnOwningThread() const
126 #ifdef DEBUG
128 #else
131 #endif
133 protected:
134 explicit BackgroundRequestChildBase(
135 MovingNotNull<RefPtr<IDBRequest>> aRequest);
137 virtual ~BackgroundRequestChildBase();
140 class BackgroundFactoryRequestChild final
141 : public BackgroundRequestChildBase,
142 public PBackgroundIDBFactoryRequestChild {
143 using PersistenceType = mozilla::dom::quota::PersistenceType;
145 friend IDBFactory;
146 friend class BackgroundFactoryChild;
147 friend class BackgroundDatabaseChild;
148 friend class PermissionRequestChild;
149 friend class PermissionRequestParent;
151 const SafeRefPtr<IDBFactory> mFactory;
153 // Normally when opening of a database is successful, we receive a database
154 // actor in request response, so we can use it to call ReleaseDOMObject()
155 // which clears temporary strong reference to IDBDatabase.
156 // However, when there's an error, we don't receive a database actor and
157 // IDBRequest::mTransaction is already cleared (must be). So the only way how
158 // to call ReleaseDOMObject() is to have a back-reference to database actor.
159 // This creates a weak ref cycle between
160 // BackgroundFactoryRequestChild (using mDatabaseActor member) and
161 // BackgroundDatabaseChild actor (using mOpenRequestActor member).
162 // mDatabaseActor is set in EnsureDOMObject() and cleared in
163 // ReleaseDOMObject().
164 BackgroundDatabaseChild* mDatabaseActor;
166 const uint64_t mRequestedVersion;
167 const bool mIsDeleteOp;
169 public:
170 NotNull<IDBOpenDBRequest*> GetOpenDBRequest() const;
172 private:
173 // Only created by IDBFactory.
174 BackgroundFactoryRequestChild(
175 SafeRefPtr<IDBFactory> aFactory,
176 MovingNotNull<RefPtr<IDBOpenDBRequest>> aOpenRequest, bool aIsDeleteOp,
177 uint64_t aRequestedVersion);
179 // Only destroyed by BackgroundFactoryChild.
180 ~BackgroundFactoryRequestChild();
182 void SetDatabaseActor(BackgroundDatabaseChild* aActor);
184 void HandleResponse(nsresult aResponse);
186 void HandleResponse(const OpenDatabaseRequestResponse& aResponse);
188 void HandleResponse(const DeleteDatabaseRequestResponse& aResponse);
190 public:
191 // IPDL methods are only called by IPDL.
192 void ActorDestroy(ActorDestroyReason aWhy) override;
194 mozilla::ipc::IPCResult Recv__delete__(
195 const FactoryRequestResponse& aResponse);
197 mozilla::ipc::IPCResult RecvPermissionChallenge(
198 PrincipalInfo&& aPrincipalInfo);
200 mozilla::ipc::IPCResult RecvBlocked(uint64_t aCurrentVersion);
203 class BackgroundDatabaseChild final : public PBackgroundIDBDatabaseChild {
204 friend class BackgroundFactoryChild;
205 friend class BackgroundFactoryRequestChild;
206 friend IDBDatabase;
208 UniquePtr<DatabaseSpec> mSpec;
209 RefPtr<IDBDatabase> mTemporaryStrongDatabase;
210 BackgroundFactoryRequestChild* mOpenRequestActor;
211 IDBDatabase* mDatabase;
213 public:
214 void AssertIsOnOwningThread() const
215 #ifdef DEBUG
217 #else
220 #endif
222 const DatabaseSpec* Spec() const {
223 AssertIsOnOwningThread();
224 return mSpec.get();
227 IDBDatabase* GetDOMObject() const {
228 AssertIsOnOwningThread();
229 return mDatabase;
232 bool SendDeleteMe() = delete;
234 private:
235 // Only constructed by BackgroundFactoryChild.
236 BackgroundDatabaseChild(const DatabaseSpec& aSpec,
237 BackgroundFactoryRequestChild* aOpenRequest);
239 // Only destroyed by BackgroundFactoryChild.
240 ~BackgroundDatabaseChild();
242 void SendDeleteMeInternal();
244 [[nodiscard]] bool EnsureDOMObject();
246 void ReleaseDOMObject();
248 public:
249 // IPDL methods are only called by IPDL.
250 void ActorDestroy(ActorDestroyReason aWhy) override;
252 PBackgroundIDBDatabaseFileChild* AllocPBackgroundIDBDatabaseFileChild(
253 const IPCBlob& aIPCBlob);
255 bool DeallocPBackgroundIDBDatabaseFileChild(
256 PBackgroundIDBDatabaseFileChild* aActor) const;
258 already_AddRefed<PBackgroundIDBVersionChangeTransactionChild>
259 AllocPBackgroundIDBVersionChangeTransactionChild(uint64_t aCurrentVersion,
260 uint64_t aRequestedVersion,
261 int64_t aNextObjectStoreId,
262 int64_t aNextIndexId);
264 mozilla::ipc::IPCResult RecvPBackgroundIDBVersionChangeTransactionConstructor(
265 PBackgroundIDBVersionChangeTransactionChild* aActor,
266 const uint64_t& aCurrentVersion, const uint64_t& aRequestedVersion,
267 const int64_t& aNextObjectStoreId, const int64_t& aNextIndexId) override;
269 mozilla::ipc::IPCResult RecvVersionChange(uint64_t aOldVersion,
270 Maybe<uint64_t> aNewVersion);
272 mozilla::ipc::IPCResult RecvInvalidate();
274 mozilla::ipc::IPCResult RecvCloseAfterInvalidationComplete();
277 class BackgroundVersionChangeTransactionChild;
279 class BackgroundTransactionBase {
280 friend class BackgroundVersionChangeTransactionChild;
282 // mTemporaryStrongTransaction is strong and is only valid until the end of
283 // NoteComplete() member function or until the NoteActorDestroyed() member
284 // function is called.
285 SafeRefPtr<IDBTransaction> mTemporaryStrongTransaction;
287 protected:
288 // mTransaction is weak and is valid until the NoteActorDestroyed() member
289 // function is called.
290 IDBTransaction* mTransaction = nullptr;
292 public:
293 #ifdef DEBUG
294 virtual void AssertIsOnOwningThread() const = 0;
295 #else
296 void AssertIsOnOwningThread() const {}
297 #endif
299 IDBTransaction* GetDOMObject() const {
300 AssertIsOnOwningThread();
301 return mTransaction;
304 protected:
305 MOZ_COUNTED_DEFAULT_CTOR(BackgroundTransactionBase);
307 explicit BackgroundTransactionBase(SafeRefPtr<IDBTransaction> aTransaction);
309 MOZ_COUNTED_DTOR_VIRTUAL(BackgroundTransactionBase);
311 void NoteActorDestroyed();
313 void NoteComplete();
315 private:
316 // Only called by BackgroundVersionChangeTransactionChild.
317 void SetDOMTransaction(SafeRefPtr<IDBTransaction> aTransaction);
320 class BackgroundTransactionChild final : public BackgroundTransactionBase,
321 public PBackgroundIDBTransactionChild {
322 friend class BackgroundDatabaseChild;
323 friend IDBDatabase;
325 public:
326 NS_INLINE_DECL_REFCOUNTING(BackgroundTransactionChild, override)
328 #ifdef DEBUG
329 void AssertIsOnOwningThread() const override;
330 #endif
332 void SendDeleteMeInternal();
334 bool SendDeleteMe() = delete;
336 private:
337 // Only created by IDBDatabase.
338 explicit BackgroundTransactionChild(SafeRefPtr<IDBTransaction> aTransaction);
340 // Only destroyed by BackgroundDatabaseChild.
341 ~BackgroundTransactionChild();
343 public:
344 // IPDL methods are only called by IPDL.
345 void ActorDestroy(ActorDestroyReason aWhy) override;
347 mozilla::ipc::IPCResult RecvComplete(nsresult aResult);
349 PBackgroundIDBRequestChild* AllocPBackgroundIDBRequestChild(
350 const RequestParams& aParams);
352 bool DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor);
354 PBackgroundIDBCursorChild* AllocPBackgroundIDBCursorChild(
355 const OpenCursorParams& aParams);
357 bool DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor);
360 class BackgroundVersionChangeTransactionChild final
361 : public BackgroundTransactionBase,
362 public PBackgroundIDBVersionChangeTransactionChild {
363 friend class BackgroundDatabaseChild;
365 IDBOpenDBRequest* mOpenDBRequest;
367 public:
368 NS_INLINE_DECL_REFCOUNTING(BackgroundVersionChangeTransactionChild, override)
370 #ifdef DEBUG
371 void AssertIsOnOwningThread() const override;
372 #endif
374 void SendDeleteMeInternal(bool aFailedConstructor);
376 bool SendDeleteMe() = delete;
378 private:
379 // Only created by BackgroundDatabaseChild.
380 explicit BackgroundVersionChangeTransactionChild(
381 IDBOpenDBRequest* aOpenDBRequest);
383 // Only destroyed by BackgroundDatabaseChild.
384 ~BackgroundVersionChangeTransactionChild();
386 // Only called by BackgroundDatabaseChild.
387 using BackgroundTransactionBase::SetDOMTransaction;
389 public:
390 // IPDL methods are only called by IPDL.
391 void ActorDestroy(ActorDestroyReason aWhy) override;
393 mozilla::ipc::IPCResult RecvComplete(nsresult aResult);
395 PBackgroundIDBRequestChild* AllocPBackgroundIDBRequestChild(
396 const RequestParams& aParams);
398 bool DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor);
400 PBackgroundIDBCursorChild* AllocPBackgroundIDBCursorChild(
401 const OpenCursorParams& aParams);
403 bool DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor);
406 class BackgroundRequestChild final : public BackgroundRequestChildBase,
407 public PBackgroundIDBRequestChild {
408 friend class BackgroundTransactionChild;
409 friend class BackgroundVersionChangeTransactionChild;
410 friend struct CloneInfo;
411 friend IDBTransaction;
413 class PreprocessHelper;
415 SafeRefPtr<IDBTransaction> mTransaction;
416 nsTArray<CloneInfo> mCloneInfos;
417 uint32_t mRunningPreprocessHelpers;
418 uint32_t mCurrentCloneDataIndex;
419 nsresult mPreprocessResultCode;
420 bool mGetAll;
422 private:
423 // Only created by IDBTransaction.
424 explicit BackgroundRequestChild(MovingNotNull<RefPtr<IDBRequest>> aRequest);
426 // Only destroyed by BackgroundTransactionChild or
427 // BackgroundVersionChangeTransactionChild.
428 ~BackgroundRequestChild();
430 void MaybeSendContinue();
432 void OnPreprocessFinished(uint32_t aCloneDataIndex,
433 UniquePtr<JSStructuredCloneData> aCloneData);
435 void OnPreprocessFailed(uint32_t aCloneDataIndex, nsresult aErrorCode);
437 UniquePtr<JSStructuredCloneData> GetNextCloneData();
439 void HandleResponse(nsresult aResponse);
441 void HandleResponse(const Key& aResponse);
443 void HandleResponse(const nsTArray<Key>& aResponse);
445 void HandleResponse(SerializedStructuredCloneReadInfo&& aResponse);
447 void HandleResponse(nsTArray<SerializedStructuredCloneReadInfo>&& aResponse);
449 void HandleResponse(JS::Handle<JS::Value> aResponse);
451 void HandleResponse(uint64_t aResponse);
453 nsresult HandlePreprocess(const PreprocessInfo& aPreprocessInfo);
455 nsresult HandlePreprocess(const nsTArray<PreprocessInfo>& aPreprocessInfos);
457 nsresult HandlePreprocessInternal(
458 const nsTArray<PreprocessInfo>& aPreprocessInfos);
460 SafeRefPtr<IDBTransaction> AcquireTransaction() const {
461 return mTransaction.clonePtr();
464 public:
465 // IPDL methods are only called by IPDL.
466 void ActorDestroy(ActorDestroyReason aWhy) override;
468 mozilla::ipc::IPCResult Recv__delete__(RequestResponse&& aResponse);
470 mozilla::ipc::IPCResult RecvPreprocess(const PreprocessParams& aParams);
473 struct CloneInfo {
474 RefPtr<BackgroundRequestChild::PreprocessHelper> mPreprocessHelper;
475 UniquePtr<JSStructuredCloneData> mCloneData;
478 class BackgroundCursorChildBase
479 : public PBackgroundIDBCursorChild,
480 public SafeRefCounted<BackgroundCursorChildBase> {
481 private:
482 NS_DECL_OWNINGTHREAD
484 public:
485 MOZ_DECLARE_REFCOUNTED_TYPENAME(
486 mozilla::dom::indexedDB::BackgroundCursorChildBase)
487 MOZ_INLINE_DECL_SAFEREFCOUNTING_INHERITED(BackgroundCursorChildBase,
488 SafeRefCounted)
490 protected:
491 ~BackgroundCursorChildBase();
493 InitializedOnce<const NotNull<IDBRequest*>> mRequest;
494 Maybe<IDBTransaction&> mTransaction;
496 // These are only set while a request is in progress.
497 RefPtr<IDBRequest> mStrongRequest;
498 RefPtr<IDBCursor> mStrongCursor;
500 const Direction mDirection;
502 BackgroundCursorChildBase(NotNull<IDBRequest*> aRequest,
503 Direction aDirection);
505 void HandleResponse(nsresult aResponse);
507 public:
508 void AssertIsOnOwningThread() const {
509 NS_ASSERT_OWNINGTHREAD(BackgroundCursorChildBase);
512 MovingNotNull<RefPtr<IDBRequest>> AcquireRequest() const;
514 NotNull<IDBRequest*> GetRequest() const {
515 AssertIsOnOwningThread();
517 return *mRequest;
520 Direction GetDirection() const {
521 AssertIsOnOwningThread();
523 return mDirection;
526 virtual void SendDeleteMeInternal() = 0;
528 virtual mozilla::ipc::IPCResult RecvResponse(CursorResponse&& aResponse) = 0;
531 template <IDBCursorType CursorType>
532 class BackgroundCursorChild final : public BackgroundCursorChildBase {
533 public:
534 using SourceType = CursorSourceType<CursorType>;
535 using ResponseType = typename CursorTypeTraits<CursorType>::ResponseType;
537 private:
538 friend class BackgroundTransactionChild;
539 friend class BackgroundVersionChangeTransactionChild;
541 InitializedOnce<const NotNull<SourceType*>> mSource;
542 IDBCursorImpl<CursorType>* mCursor;
544 std::deque<CursorData<CursorType>> mCachedResponses, mDelayedResponses;
545 bool mInFlightResponseInvalidationNeeded;
547 public:
548 BackgroundCursorChild(NotNull<IDBRequest*> aRequest, SourceType* aSource,
549 Direction aDirection);
551 void SendContinueInternal(const CursorRequestParams& aParams,
552 const CursorData<CursorType>& aCurrentData);
554 void InvalidateCachedResponses();
556 template <typename Condition>
557 void DiscardCachedResponses(const Condition& aConditionFunc);
559 SourceType* GetSource() const {
560 AssertIsOnOwningThread();
562 return *mSource;
565 void SendDeleteMeInternal() final;
567 private:
568 // Only destroyed by BackgroundTransactionChild or
569 // BackgroundVersionChangeTransactionChild.
570 ~BackgroundCursorChild();
572 void CompleteContinueRequestFromCache();
574 using BackgroundCursorChildBase::HandleResponse;
576 void HandleResponse(const void_t& aResponse);
578 void HandleResponse(nsTArray<ResponseType>&& aResponses);
580 template <typename Func>
581 void HandleMultipleCursorResponses(nsTArray<ResponseType>&& aResponses,
582 const Func& aHandleRecord);
584 template <typename... Args>
585 [[nodiscard]] RefPtr<IDBCursor> HandleIndividualCursorResponse(
586 bool aUseAsCurrentResult, Args&&... aArgs);
588 SafeRefPtr<BackgroundCursorChild> SafeRefPtrFromThis();
590 public:
591 // IPDL methods are only called by IPDL.
592 void ActorDestroy(ActorDestroyReason aWhy) override;
594 mozilla::ipc::IPCResult RecvResponse(CursorResponse&& aResponse) override;
596 // Force callers to use SendContinueInternal.
597 bool SendContinue(const CursorRequestParams& aParams, const Key& aCurrentKey,
598 const Key& aCurrentObjectStoreKey) = delete;
600 bool SendDeleteMe() = delete;
603 class BackgroundUtilsChild final : public PBackgroundIndexedDBUtilsChild {
604 friend class mozilla::ipc::BackgroundChildImpl;
605 friend IndexedDatabaseManager;
607 IndexedDatabaseManager* mManager;
609 NS_DECL_OWNINGTHREAD
611 public:
612 void AssertIsOnOwningThread() const {
613 NS_ASSERT_OWNINGTHREAD(BackgroundUtilsChild);
616 bool SendDeleteMe() = delete;
618 private:
619 // Only created by IndexedDatabaseManager.
620 explicit BackgroundUtilsChild(IndexedDatabaseManager* aManager);
622 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
623 ~BackgroundUtilsChild();
625 void SendDeleteMeInternal();
627 public:
628 // IPDL methods are only called by IPDL.
629 void ActorDestroy(ActorDestroyReason aWhy) override;
632 } // namespace mozilla::dom::indexedDB
634 #endif // mozilla_dom_indexeddb_actorschild_h__