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/. */
6
7 #ifndef mozilla_dom_indexeddb_actorschild_h__
8 #define mozilla_dom_indexeddb_actorschild_h__
9
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/PBackgroundIDBDatabaseRequestChild.h"
17 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
18 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryRequestChild.h"
19 #include "mozilla/dom/indexedDB/PBackgroundIDBRequestChild.h"
20 #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
21 #include "mozilla/dom/indexedDB/PBackgroundIDBTransactionChild.h"
22 #include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionChild.h"
23 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
24 #include "mozilla/dom/PBackgroundFileHandleChild.h"
25 #include "mozilla/dom/PBackgroundFileRequestChild.h"
26 #include "mozilla/dom/PBackgroundMutableFileChild.h"
27 #include "mozilla/InitializedOnce.h"
28 #include "mozilla/UniquePtr.h"
29 #include "nsCOMPtr.h"
30 #include "nsTArray.h"
31
32 class nsIEventTarget;
33 struct nsID;
34
35 namespace mozilla {
36 namespace ipc {
37
38 class BackgroundChildImpl;
39
40 } // namespace ipc
41
42 namespace dom {
43
44 class IDBCursor;
45 class IDBDatabase;
46 class IDBFactory;
47 class IDBFileHandle;
48 class IDBFileRequest;
49 class IDBMutableFile;
50 class IDBOpenDBRequest;
51 class IDBRequest;
52 class IndexedDatabaseManager;
53
54 namespace indexedDB {
55
56 class Key;
57 class PermissionRequestChild;
58 class PermissionRequestParent;
59 class SerializedStructuredCloneReadInfo;
60 struct CloneInfo;
61
62 } // namespace indexedDB
63 } // namespace dom
64 } // namespace mozilla
65
MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(mozilla::dom::indexedDB::CloneInfo)66 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(mozilla::dom::indexedDB::CloneInfo)
67
68 namespace mozilla {
69 namespace dom {
70 namespace indexedDB {
71
72 class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
73 friend class mozilla::ipc::BackgroundChildImpl;
74 friend IDBFactory;
75
76 // TODO: This long-lived raw pointer is very suspicious, in particular as it
77 // is used in BackgroundDatabaseChild::EnsureDOMObject to reacquire a strong
78 // reference. What ensures it is kept alive, and why can't we store a strong
79 // reference here?
80 IDBFactory* mFactory;
81
82 public:
83 NS_INLINE_DECL_REFCOUNTING(BackgroundFactoryChild, override)
84
85 void AssertIsOnOwningThread() const {
86 NS_ASSERT_OWNINGTHREAD(BackgroundFactoryChild);
87 }
88
89 IDBFactory& GetDOMObject() const {
90 AssertIsOnOwningThread();
91 MOZ_ASSERT(mFactory);
92 return *mFactory;
93 }
94
95 bool SendDeleteMe() = delete;
96
97 private:
98 // Only created by IDBFactory.
99 explicit BackgroundFactoryChild(IDBFactory& aFactory);
100
101 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
102 ~BackgroundFactoryChild();
103
104 void SendDeleteMeInternal();
105
106 public:
107 // IPDL methods are only called by IPDL.
108 void ActorDestroy(ActorDestroyReason aWhy) override;
109
110 PBackgroundIDBFactoryRequestChild* AllocPBackgroundIDBFactoryRequestChild(
111 const FactoryRequestParams& aParams);
112
113 bool DeallocPBackgroundIDBFactoryRequestChild(
114 PBackgroundIDBFactoryRequestChild* aActor);
115
116 PBackgroundIDBDatabaseChild* AllocPBackgroundIDBDatabaseChild(
117 const DatabaseSpec& aSpec, PBackgroundIDBFactoryRequestChild* aRequest);
118
119 bool DeallocPBackgroundIDBDatabaseChild(PBackgroundIDBDatabaseChild* aActor);
120
121 mozilla::ipc::IPCResult RecvPBackgroundIDBDatabaseConstructor(
122 PBackgroundIDBDatabaseChild* aActor, const DatabaseSpec& aSpec,
123 PBackgroundIDBFactoryRequestChild* aRequest) override;
124 };
125
126 class BackgroundDatabaseChild;
127
128 class BackgroundRequestChildBase {
129 protected:
130 const NotNull<RefPtr<IDBRequest>> mRequest;
131
132 public:
133 void AssertIsOnOwningThread() const
134 #ifdef DEBUG
135 ;
136 #else
137 {
138 }
139 #endif
140
141 protected:
142 explicit BackgroundRequestChildBase(
143 MovingNotNull<RefPtr<IDBRequest>> aRequest);
144
145 virtual ~BackgroundRequestChildBase();
146 };
147
148 class BackgroundFactoryRequestChild final
149 : public BackgroundRequestChildBase,
150 public PBackgroundIDBFactoryRequestChild {
151 typedef mozilla::dom::quota::PersistenceType PersistenceType;
152
153 friend IDBFactory;
154 friend class BackgroundFactoryChild;
155 friend class BackgroundDatabaseChild;
156 friend class PermissionRequestChild;
157 friend class PermissionRequestParent;
158
159 const SafeRefPtr<IDBFactory> mFactory;
160
161 // Normally when opening of a database is successful, we receive a database
162 // actor in request response, so we can use it to call ReleaseDOMObject()
163 // which clears temporary strong reference to IDBDatabase.
164 // However, when there's an error, we don't receive a database actor and
165 // IDBRequest::mTransaction is already cleared (must be). So the only way how
166 // to call ReleaseDOMObject() is to have a back-reference to database actor.
167 // This creates a weak ref cycle between
168 // BackgroundFactoryRequestChild (using mDatabaseActor member) and
169 // BackgroundDatabaseChild actor (using mOpenRequestActor member).
170 // mDatabaseActor is set in EnsureDOMObject() and cleared in
171 // ReleaseDOMObject().
172 BackgroundDatabaseChild* mDatabaseActor;
173
174 const uint64_t mRequestedVersion;
175 const bool mIsDeleteOp;
176
177 public:
178 NotNull<IDBOpenDBRequest*> GetOpenDBRequest() const;
179
180 private:
181 // Only created by IDBFactory.
182 BackgroundFactoryRequestChild(
183 SafeRefPtr<IDBFactory> aFactory,
184 MovingNotNull<RefPtr<IDBOpenDBRequest>> aOpenRequest, bool aIsDeleteOp,
185 uint64_t aRequestedVersion);
186
187 // Only destroyed by BackgroundFactoryChild.
188 ~BackgroundFactoryRequestChild();
189
190 void SetDatabaseActor(BackgroundDatabaseChild* aActor);
191
192 bool HandleResponse(nsresult aResponse);
193
194 bool HandleResponse(const OpenDatabaseRequestResponse& aResponse);
195
196 bool HandleResponse(const DeleteDatabaseRequestResponse& aResponse);
197
198 public:
199 // IPDL methods are only called by IPDL.
200 void ActorDestroy(ActorDestroyReason aWhy) override;
201
202 mozilla::ipc::IPCResult Recv__delete__(
203 const FactoryRequestResponse& aResponse);
204
205 mozilla::ipc::IPCResult RecvPermissionChallenge(
206 PrincipalInfo&& aPrincipalInfo);
207
208 mozilla::ipc::IPCResult RecvBlocked(uint64_t aCurrentVersion);
209 };
210
211 class BackgroundDatabaseChild final : public PBackgroundIDBDatabaseChild {
212 friend class BackgroundFactoryChild;
213 friend class BackgroundFactoryRequestChild;
214 friend IDBDatabase;
215
216 UniquePtr<DatabaseSpec> mSpec;
217 RefPtr<IDBDatabase> mTemporaryStrongDatabase;
218 BackgroundFactoryRequestChild* mOpenRequestActor;
219 IDBDatabase* mDatabase;
220
221 public:
222 void AssertIsOnOwningThread() const
223 #ifdef DEBUG
224 ;
225 #else
226 {
227 }
228 #endif
229
230 const DatabaseSpec* Spec() const {
231 AssertIsOnOwningThread();
232 return mSpec.get();
233 }
234
235 IDBDatabase* GetDOMObject() const {
236 AssertIsOnOwningThread();
237 return mDatabase;
238 }
239
240 bool SendDeleteMe() = delete;
241
242 private:
243 // Only constructed by BackgroundFactoryChild.
244 BackgroundDatabaseChild(const DatabaseSpec& aSpec,
245 BackgroundFactoryRequestChild* aOpenRequest);
246
247 // Only destroyed by BackgroundFactoryChild.
248 ~BackgroundDatabaseChild();
249
250 void SendDeleteMeInternal();
251
252 [[nodiscard]] bool EnsureDOMObject();
253
254 void ReleaseDOMObject();
255
256 public:
257 // IPDL methods are only called by IPDL.
258 void ActorDestroy(ActorDestroyReason aWhy) override;
259
260 PBackgroundIDBDatabaseFileChild* AllocPBackgroundIDBDatabaseFileChild(
261 const IPCBlob& aIPCBlob);
262
263 bool DeallocPBackgroundIDBDatabaseFileChild(
264 PBackgroundIDBDatabaseFileChild* aActor);
265
266 PBackgroundIDBDatabaseRequestChild* AllocPBackgroundIDBDatabaseRequestChild(
267 const DatabaseRequestParams& aParams);
268
269 bool DeallocPBackgroundIDBDatabaseRequestChild(
270 PBackgroundIDBDatabaseRequestChild* aActor);
271
272 already_AddRefed<PBackgroundIDBVersionChangeTransactionChild>
273 AllocPBackgroundIDBVersionChangeTransactionChild(uint64_t aCurrentVersion,
274 uint64_t aRequestedVersion,
275 int64_t aNextObjectStoreId,
276 int64_t aNextIndexId);
277
278 mozilla::ipc::IPCResult RecvPBackgroundIDBVersionChangeTransactionConstructor(
279 PBackgroundIDBVersionChangeTransactionChild* aActor,
280 const uint64_t& aCurrentVersion, const uint64_t& aRequestedVersion,
281 const int64_t& aNextObjectStoreId, const int64_t& aNextIndexId) override;
282
283 PBackgroundMutableFileChild* AllocPBackgroundMutableFileChild(
284 const nsString& aName, const nsString& aType);
285
286 bool DeallocPBackgroundMutableFileChild(PBackgroundMutableFileChild* aActor);
287
288 mozilla::ipc::IPCResult RecvVersionChange(uint64_t aOldVersion,
289 Maybe<uint64_t> aNewVersion);
290
291 mozilla::ipc::IPCResult RecvInvalidate();
292
293 mozilla::ipc::IPCResult RecvCloseAfterInvalidationComplete();
294 };
295
296 class BackgroundDatabaseRequestChild final
297 : public BackgroundRequestChildBase,
298 public PBackgroundIDBDatabaseRequestChild {
299 friend class BackgroundDatabaseChild;
300 friend IDBDatabase;
301
302 RefPtr<IDBDatabase> mDatabase;
303
304 private:
305 // Only created by IDBDatabase.
306 BackgroundDatabaseRequestChild(IDBDatabase* aDatabase,
307 MovingNotNull<RefPtr<IDBRequest>> aRequest);
308
309 // Only destroyed by BackgroundDatabaseChild.
310 ~BackgroundDatabaseRequestChild();
311
312 bool HandleResponse(nsresult aResponse);
313
314 bool HandleResponse(const CreateFileRequestResponse& aResponse);
315
316 public:
317 // IPDL methods are only called by IPDL.
318 mozilla::ipc::IPCResult Recv__delete__(
319 const DatabaseRequestResponse& aResponse);
320 };
321
322 class BackgroundVersionChangeTransactionChild;
323
324 class BackgroundTransactionBase {
325 friend class BackgroundVersionChangeTransactionChild;
326
327 // mTemporaryStrongTransaction is strong and is only valid until the end of
328 // NoteComplete() member function or until the NoteActorDestroyed() member
329 // function is called.
330 SafeRefPtr<IDBTransaction> mTemporaryStrongTransaction;
331
332 protected:
333 // mTransaction is weak and is valid until the NoteActorDestroyed() member
334 // function is called.
335 IDBTransaction* mTransaction = nullptr;
336
337 public:
338 #ifdef DEBUG
339 virtual void AssertIsOnOwningThread() const = 0;
340 #else
341 void AssertIsOnOwningThread() const {}
342 #endif
343
344 IDBTransaction* GetDOMObject() const {
345 AssertIsOnOwningThread();
346 return mTransaction;
347 }
348
349 protected:
350 MOZ_COUNTED_DEFAULT_CTOR(BackgroundTransactionBase);
351
352 explicit BackgroundTransactionBase(SafeRefPtr<IDBTransaction> aTransaction);
353
354 MOZ_COUNTED_DTOR_VIRTUAL(BackgroundTransactionBase);
355
356 void NoteActorDestroyed();
357
358 void NoteComplete();
359
360 private:
361 // Only called by BackgroundVersionChangeTransactionChild.
362 void SetDOMTransaction(SafeRefPtr<IDBTransaction> aTransaction);
363 };
364
365 class BackgroundTransactionChild final : public BackgroundTransactionBase,
366 public PBackgroundIDBTransactionChild {
367 friend class BackgroundDatabaseChild;
368 friend IDBDatabase;
369
370 public:
371 NS_INLINE_DECL_REFCOUNTING(BackgroundTransactionChild, override)
372
373 #ifdef DEBUG
374 void AssertIsOnOwningThread() const override;
375 #endif
376
377 void SendDeleteMeInternal();
378
379 bool SendDeleteMe() = delete;
380
381 private:
382 // Only created by IDBDatabase.
383 explicit BackgroundTransactionChild(SafeRefPtr<IDBTransaction> aTransaction);
384
385 // Only destroyed by BackgroundDatabaseChild.
386 ~BackgroundTransactionChild();
387
388 public:
389 // IPDL methods are only called by IPDL.
390 void ActorDestroy(ActorDestroyReason aWhy) override;
391
392 mozilla::ipc::IPCResult RecvComplete(nsresult aResult);
393
394 PBackgroundIDBRequestChild* AllocPBackgroundIDBRequestChild(
395 const RequestParams& aParams);
396
397 bool DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor);
398
399 PBackgroundIDBCursorChild* AllocPBackgroundIDBCursorChild(
400 const OpenCursorParams& aParams);
401
402 bool DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor);
403 };
404
405 class BackgroundVersionChangeTransactionChild final
406 : public BackgroundTransactionBase,
407 public PBackgroundIDBVersionChangeTransactionChild {
408 friend class BackgroundDatabaseChild;
409
410 IDBOpenDBRequest* mOpenDBRequest;
411
412 public:
413 NS_INLINE_DECL_REFCOUNTING(BackgroundVersionChangeTransactionChild, override)
414
415 #ifdef DEBUG
416 void AssertIsOnOwningThread() const override;
417 #endif
418
419 void SendDeleteMeInternal(bool aFailedConstructor);
420
421 bool SendDeleteMe() = delete;
422
423 private:
424 // Only created by BackgroundDatabaseChild.
425 explicit BackgroundVersionChangeTransactionChild(
426 IDBOpenDBRequest* aOpenDBRequest);
427
428 // Only destroyed by BackgroundDatabaseChild.
429 ~BackgroundVersionChangeTransactionChild();
430
431 // Only called by BackgroundDatabaseChild.
432 using BackgroundTransactionBase::SetDOMTransaction;
433
434 public:
435 // IPDL methods are only called by IPDL.
436 void ActorDestroy(ActorDestroyReason aWhy) override;
437
438 mozilla::ipc::IPCResult RecvComplete(nsresult aResult);
439
440 PBackgroundIDBRequestChild* AllocPBackgroundIDBRequestChild(
441 const RequestParams& aParams);
442
443 bool DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor);
444
445 PBackgroundIDBCursorChild* AllocPBackgroundIDBCursorChild(
446 const OpenCursorParams& aParams);
447
448 bool DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor);
449 };
450
451 class BackgroundMutableFileChild final : public PBackgroundMutableFileChild {
452 friend class BackgroundDatabaseChild;
453 friend IDBMutableFile;
454
455 RefPtr<IDBMutableFile> mTemporaryStrongMutableFile;
456 IDBMutableFile* mMutableFile;
457 nsString mName;
458 nsString mType;
459
460 public:
461 void AssertIsOnOwningThread() const
462 #ifdef DEBUG
463 ;
464 #else
465 {
466 }
467 #endif
468
469 void EnsureDOMObject();
470
471 IDBMutableFile* GetDOMObject() const {
472 AssertIsOnOwningThread();
473 return mMutableFile;
474 }
475
476 void ReleaseDOMObject();
477
478 bool SendDeleteMe() = delete;
479
480 private:
481 // Only constructed by BackgroundDatabaseChild.
482 BackgroundMutableFileChild(const nsAString& aName, const nsAString& aType);
483
484 // Only destroyed by BackgroundDatabaseChild.
485 ~BackgroundMutableFileChild();
486
487 void SendDeleteMeInternal();
488
489 public:
490 // IPDL methods are only called by IPDL.
491 void ActorDestroy(ActorDestroyReason aWhy) override;
492
493 PBackgroundFileHandleChild* AllocPBackgroundFileHandleChild(
494 const FileMode& aMode);
495
496 bool DeallocPBackgroundFileHandleChild(PBackgroundFileHandleChild* aActor);
497 };
498
499 class BackgroundRequestChild final : public BackgroundRequestChildBase,
500 public PBackgroundIDBRequestChild {
501 friend class BackgroundTransactionChild;
502 friend class BackgroundVersionChangeTransactionChild;
503 friend struct CloneInfo;
504 friend IDBTransaction;
505
506 class PreprocessHelper;
507
508 SafeRefPtr<IDBTransaction> mTransaction;
509 nsTArray<CloneInfo> mCloneInfos;
510 uint32_t mRunningPreprocessHelpers;
511 uint32_t mCurrentCloneDataIndex;
512 nsresult mPreprocessResultCode;
513 bool mGetAll;
514
515 private:
516 // Only created by IDBTransaction.
517 explicit BackgroundRequestChild(MovingNotNull<RefPtr<IDBRequest>> aRequest);
518
519 // Only destroyed by BackgroundTransactionChild or
520 // BackgroundVersionChangeTransactionChild.
521 ~BackgroundRequestChild();
522
523 void MaybeSendContinue();
524
525 void OnPreprocessFinished(uint32_t aCloneDataIndex,
526 UniquePtr<JSStructuredCloneData> aCloneData);
527
528 void OnPreprocessFailed(uint32_t aCloneDataIndex, nsresult aErrorCode);
529
530 UniquePtr<JSStructuredCloneData> GetNextCloneData();
531
532 void HandleResponse(nsresult aResponse);
533
534 void HandleResponse(const Key& aResponse);
535
536 void HandleResponse(const nsTArray<Key>& aResponse);
537
538 void HandleResponse(SerializedStructuredCloneReadInfo&& aResponse);
539
540 void HandleResponse(nsTArray<SerializedStructuredCloneReadInfo>&& aResponse);
541
542 void HandleResponse(JS::Handle<JS::Value> aResponse);
543
544 void HandleResponse(uint64_t aResponse);
545
546 nsresult HandlePreprocess(const PreprocessInfo& aPreprocessInfo);
547
548 nsresult HandlePreprocess(const nsTArray<PreprocessInfo>& aPreprocessInfos);
549
550 nsresult HandlePreprocessInternal(
551 const nsTArray<PreprocessInfo>& aPreprocessInfos);
552
553 SafeRefPtr<IDBTransaction> AcquireTransaction() const {
554 return mTransaction.clonePtr();
555 }
556
557 public:
558 // IPDL methods are only called by IPDL.
559 void ActorDestroy(ActorDestroyReason aWhy) override;
560
561 mozilla::ipc::IPCResult Recv__delete__(RequestResponse&& aResponse);
562
563 mozilla::ipc::IPCResult RecvPreprocess(const PreprocessParams& aParams);
564 };
565
566 struct CloneInfo {
567 RefPtr<BackgroundRequestChild::PreprocessHelper> mPreprocessHelper;
568 UniquePtr<JSStructuredCloneData> mCloneData;
569 };
570
571 class BackgroundCursorChildBase
572 : public PBackgroundIDBCursorChild,
573 public SafeRefCounted<BackgroundCursorChildBase> {
574 private:
575 NS_DECL_OWNINGTHREAD
576
577 public:
578 MOZ_DECLARE_REFCOUNTED_TYPENAME(
579 mozilla::dom::indexedDB::BackgroundCursorChildBase)
580 MOZ_INLINE_DECL_SAFEREFCOUNTING_INHERITED(BackgroundCursorChildBase,
581 SafeRefCounted)
582
583 protected:
584 ~BackgroundCursorChildBase();
585
586 InitializedOnce<const NotNull<IDBRequest*>> mRequest;
587 Maybe<IDBTransaction&> mTransaction;
588
589 // These are only set while a request is in progress.
590 RefPtr<IDBRequest> mStrongRequest;
591 RefPtr<IDBCursor> mStrongCursor;
592
593 const Direction mDirection;
594
595 BackgroundCursorChildBase(NotNull<IDBRequest*> aRequest,
596 Direction aDirection);
597
598 void HandleResponse(nsresult aResponse);
599
600 public:
601 void AssertIsOnOwningThread() const {
602 NS_ASSERT_OWNINGTHREAD(BackgroundCursorChildBase);
603 }
604
605 MovingNotNull<RefPtr<IDBRequest>> AcquireRequest() const;
606
607 NotNull<IDBRequest*> GetRequest() const {
608 AssertIsOnOwningThread();
609
610 return *mRequest;
611 }
612
613 Direction GetDirection() const {
614 AssertIsOnOwningThread();
615
616 return mDirection;
617 }
618
619 virtual void SendDeleteMeInternal() = 0;
620
621 virtual mozilla::ipc::IPCResult RecvResponse(CursorResponse&& aResponse) = 0;
622 };
623
624 template <IDBCursorType CursorType>
625 class BackgroundCursorChild final : public BackgroundCursorChildBase {
626 public:
627 using SourceType = CursorSourceType<CursorType>;
628 using ResponseType = typename CursorTypeTraits<CursorType>::ResponseType;
629
630 private:
631 friend class BackgroundTransactionChild;
632 friend class BackgroundVersionChangeTransactionChild;
633
634 InitializedOnce<const NotNull<SourceType*>> mSource;
635 IDBCursorImpl<CursorType>* mCursor;
636
637 std::deque<CursorData<CursorType>> mCachedResponses, mDelayedResponses;
638 bool mInFlightResponseInvalidationNeeded;
639
640 public:
641 BackgroundCursorChild(NotNull<IDBRequest*> aRequest, SourceType* aSource,
642 Direction aDirection);
643
644 void SendContinueInternal(const CursorRequestParams& aParams,
645 const CursorData<CursorType>& aCurrentData);
646
647 void InvalidateCachedResponses();
648
649 template <typename Condition>
650 void DiscardCachedResponses(const Condition& aConditionFunc);
651
652 SourceType* GetSource() const {
653 AssertIsOnOwningThread();
654
655 return *mSource;
656 }
657
658 void SendDeleteMeInternal() final;
659
660 private:
661 // Only destroyed by BackgroundTransactionChild or
662 // BackgroundVersionChangeTransactionChild.
663 ~BackgroundCursorChild();
664
665 void CompleteContinueRequestFromCache();
666
667 using BackgroundCursorChildBase::HandleResponse;
668
669 void HandleResponse(const void_t& aResponse);
670
671 void HandleResponse(nsTArray<ResponseType>&& aResponses);
672
673 template <typename Func>
674 void HandleMultipleCursorResponses(nsTArray<ResponseType>&& aResponses,
675 const Func& aHandleRecord);
676
677 template <typename... Args>
678 [[nodiscard]] RefPtr<IDBCursor> HandleIndividualCursorResponse(
679 bool aUseAsCurrentResult, Args&&... aArgs);
680
681 SafeRefPtr<BackgroundCursorChild> SafeRefPtrFromThis();
682
683 public:
684 // IPDL methods are only called by IPDL.
685 void ActorDestroy(ActorDestroyReason aWhy) override;
686
687 mozilla::ipc::IPCResult RecvResponse(CursorResponse&& aResponse) override;
688
689 // Force callers to use SendContinueInternal.
690 bool SendContinue(const CursorRequestParams& aParams, const Key& aCurrentKey,
691 const Key& aCurrentObjectStoreKey) = delete;
692
693 bool SendDeleteMe() = delete;
694 };
695
696 class BackgroundFileHandleChild : public PBackgroundFileHandleChild {
697 friend class BackgroundMutableFileChild;
698 friend IDBMutableFile;
699
700 // mTemporaryStrongFileHandle is strong and is only valid until the end of
701 // NoteComplete() member function or until the NoteActorDestroyed() member
702 // function is called.
703 RefPtr<IDBFileHandle> mTemporaryStrongFileHandle;
704
705 // mFileHandle is weak and is valid until the NoteActorDestroyed() member
706 // function is called.
707 IDBFileHandle* mFileHandle;
708
709 public:
710 void AssertIsOnOwningThread() const
711 #ifdef DEBUG
712 ;
713 #else
714 {
715 }
716 #endif
717
718 void SendDeleteMeInternal();
719
720 bool SendDeleteMe() = delete;
721
722 private:
723 // Only created by IDBMutableFile.
724 explicit BackgroundFileHandleChild(IDBFileHandle* aFileHandle);
725
726 ~BackgroundFileHandleChild();
727
728 void NoteActorDestroyed();
729
730 void NoteComplete();
731
732 public:
733 // IPDL methods are only called by IPDL.
734 void ActorDestroy(ActorDestroyReason aWhy) override;
735
736 mozilla::ipc::IPCResult RecvComplete(bool aAborted);
737
738 PBackgroundFileRequestChild* AllocPBackgroundFileRequestChild(
739 const FileRequestParams& aParams);
740
741 bool DeallocPBackgroundFileRequestChild(PBackgroundFileRequestChild* aActor);
742 };
743
744 class BackgroundFileRequestChild final : public PBackgroundFileRequestChild {
745 friend class BackgroundFileHandleChild;
746 friend IDBFileHandle;
747
748 RefPtr<IDBFileRequest> mFileRequest;
749 RefPtr<IDBFileHandle> mFileHandle;
750 bool mActorDestroyed;
751
752 public:
753 void AssertIsOnOwningThread() const
754 #ifdef DEBUG
755 ;
756 #else
757 {
758 }
759 #endif
760
761 private:
762 // Only created by IDBFileHandle.
763 explicit BackgroundFileRequestChild(IDBFileRequest* aFileRequest);
764
765 // Only destroyed by BackgroundFileHandleChild.
766 ~BackgroundFileRequestChild();
767
768 void HandleResponse(nsresult aResponse);
769
770 void HandleResponse(const nsCString& aResponse);
771
772 void HandleResponse(const FileRequestMetadata& aResponse);
773
774 void HandleResponse(JS::Handle<JS::Value> aResponse);
775
776 public:
777 // IPDL methods are only called by IPDL.
778 void ActorDestroy(ActorDestroyReason aWhy) override;
779
780 mozilla::ipc::IPCResult Recv__delete__(const FileRequestResponse& aResponse);
781
782 mozilla::ipc::IPCResult RecvProgress(uint64_t aProgress,
783 uint64_t aProgressMax);
784 };
785
786 class BackgroundUtilsChild final : public PBackgroundIndexedDBUtilsChild {
787 friend class mozilla::ipc::BackgroundChildImpl;
788 friend IndexedDatabaseManager;
789
790 IndexedDatabaseManager* mManager;
791
792 NS_DECL_OWNINGTHREAD
793
794 public:
795 void AssertIsOnOwningThread() const {
796 NS_ASSERT_OWNINGTHREAD(BackgroundUtilsChild);
797 }
798
799 bool SendDeleteMe() = delete;
800
801 private:
802 // Only created by IndexedDatabaseManager.
803 explicit BackgroundUtilsChild(IndexedDatabaseManager* aManager);
804
805 // Only destroyed by mozilla::ipc::BackgroundChildImpl.
806 ~BackgroundUtilsChild();
807
808 void SendDeleteMeInternal();
809
810 public:
811 // IPDL methods are only called by IPDL.
812 void ActorDestroy(ActorDestroyReason aWhy) override;
813 };
814
815 } // namespace indexedDB
816 } // namespace dom
817 } // namespace mozilla
818
819 #endif // mozilla_dom_indexeddb_actorschild_h__
820