CacheChild.cpp (3883B)
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/. */ 6 7 #include "mozilla/dom/cache/CacheChild.h" 8 9 #include "CacheWorkerRef.h" 10 #include "mozilla/dom/cache/ActorUtils.h" 11 #include "mozilla/dom/cache/Cache.h" 12 #include "mozilla/dom/cache/CacheOpChild.h" 13 14 namespace mozilla::dom::cache { 15 16 // Declared in ActorUtils.h 17 already_AddRefed<PCacheChild> AllocPCacheChild(ActorChild* aParentActor) { 18 return MakeAndAddRef<CacheChild>(aParentActor); 19 } 20 21 // Declared in ActorUtils.h 22 void DeallocPCacheChild(PCacheChild* aActor) { delete aActor; } 23 24 CacheChild::CacheChild(ActorChild* aParentActor) 25 : mParentActor(aParentActor), 26 mListener(nullptr), 27 mLocked(false), 28 mDelayedDestroy(false) { 29 MOZ_COUNT_CTOR(cache::CacheChild); 30 } 31 32 CacheChild::~CacheChild() { 33 MOZ_COUNT_DTOR(cache::CacheChild); 34 NS_ASSERT_OWNINGTHREAD(CacheChild); 35 MOZ_DIAGNOSTIC_ASSERT(!mListener); 36 MOZ_DIAGNOSTIC_ASSERT(!mLocked); 37 } 38 39 void CacheChild::SetListener(CacheChildListener* aListener) { 40 NS_ASSERT_OWNINGTHREAD(CacheChild); 41 MOZ_DIAGNOSTIC_ASSERT(!mListener); 42 mListener = aListener; 43 MOZ_DIAGNOSTIC_ASSERT(mListener); 44 } 45 46 void CacheChild::ClearListener() { 47 NS_ASSERT_OWNINGTHREAD(CacheChild); 48 MOZ_DIAGNOSTIC_ASSERT(mListener); 49 mListener = nullptr; 50 } 51 52 void CacheChild::StartDestroyFromListener() { 53 NS_ASSERT_OWNINGTHREAD(CacheChild); 54 55 // The listener should be held alive by any async operations, so if it 56 // is going away then there must not be any child actors. This in turn 57 // ensures that StartDestroy() will not trigger the delayed path. 58 MOZ_DIAGNOSTIC_ASSERT(NumChildActors() == 0); 59 StartDestroy(); 60 } 61 62 void CacheChild::DestroyInternal() { 63 CacheChildListener* listener = mListener; 64 65 // StartDestroy() can get called from either Cache or the WorkerRef. 66 // Theoretically we can get double called if the right race happens. Handle 67 // that by just ignoring the second StartDestroy() call. 68 if (!listener) { 69 return; 70 } 71 72 listener->OnActorDestroy(this); 73 74 // Cache listener should call ClearListener() in OnActorDestroy() 75 MOZ_DIAGNOSTIC_ASSERT(!mListener); 76 77 // Start actor destruction from parent process 78 QM_WARNONLY_TRY(OkIf(SendTeardown())); 79 } 80 81 void CacheChild::StartDestroy() { 82 NS_ASSERT_OWNINGTHREAD(CacheChild); 83 84 if (NumChildActors() != 0 || mLocked) { 85 mDelayedDestroy = true; 86 return; 87 } 88 89 DestroyInternal(); 90 } 91 92 void CacheChild::ActorDestroy(ActorDestroyReason aReason) { 93 NS_ASSERT_OWNINGTHREAD(CacheChild); 94 CacheChildListener* listener = mListener; 95 if (listener) { 96 listener->OnActorDestroy(this); 97 // Cache listener should call ClearListener() in OnActorDestroy() 98 MOZ_DIAGNOSTIC_ASSERT(!mListener); 99 } 100 101 if (mParentActor) { 102 mParentActor->NoteDeletedActor(); 103 } 104 105 RemoveWorkerRef(); 106 } 107 108 void CacheChild::NoteDeletedActor() { 109 // Check to see if DestroyInternal was delayed because there were still active 110 // CacheOpChilds when StartDestroy was called from WorkerRef notification. If 111 // the last CacheOpChild is getting destructed; it's the time for us to 112 // SendTearDown to the other side. 113 if (NumChildActors() == 0 && mDelayedDestroy && !mLocked) DestroyInternal(); 114 } 115 116 already_AddRefed<PCacheOpChild> CacheChild::AllocPCacheOpChild( 117 const CacheOpArgs& aOpArgs) { 118 MOZ_CRASH("CacheOpChild should be manually constructed."); 119 return nullptr; 120 } 121 122 void CacheChild::Lock() { 123 NS_ASSERT_OWNINGTHREAD(CacheChild); 124 MOZ_DIAGNOSTIC_ASSERT(!mLocked); 125 mLocked = true; 126 } 127 128 void CacheChild::Unlock() { 129 NS_ASSERT_OWNINGTHREAD(CacheChild); 130 MOZ_DIAGNOSTIC_ASSERT(mLocked); 131 mLocked = false; 132 } 133 134 } // namespace mozilla::dom::cache