diff --git a/dom/cache/CacheStorage.cpp b/dom/cache/CacheStorage.cpp index 8e600556fd5c..bc2ede67dded 100644 --- a/dom/cache/CacheStorage.cpp +++ b/dom/cache/CacheStorage.cpp @@ -50,11 +50,10 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::cache::CacheStorage, NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CacheStorage) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) - NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback) NS_INTERFACE_MAP_END // We cannot reference IPC types in a webidl binding implementation header. So -// define this in the .cpp and use heap storage in the mPendingRequests list. +// define this in the .cpp. struct CacheStorage::Entry final { RefPtr mPromise; @@ -275,7 +274,6 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal, : mNamespace(aNamespace) , mGlobal(aGlobal) , mPrincipalInfo(MakeUnique(aPrincipalInfo)) - , mWorkerHolder(aWorkerHolder) , mActor(nullptr) , mStatus(NS_OK) { @@ -283,19 +281,26 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal, // If the PBackground actor is already initialized then we can // immediately use it - PBackgroundChild* actor = BackgroundChild::GetForCurrentThread(); - if (actor) { - ActorCreated(actor); + PBackgroundChild* actor = BackgroundChild::GetOrCreateForCurrentThread(); + if (NS_WARN_IF(!actor)) { + mStatus = NS_ERROR_UNEXPECTED; return; } - // Otherwise we must begin the PBackground initialization process and - // wait for the async ActorCreated() callback. - MOZ_ASSERT(NS_IsMainThread()); - bool ok = BackgroundChild::GetOrCreateForCurrentThread(this); - if (NS_WARN_IF(!ok)) { - ActorFailed(); + // WorkerHolder ownership is passed to the CacheStorageChild actor and any + // actors it may create. The WorkerHolder will keep the worker thread alive + // until the actors can gracefully shutdown. + CacheStorageChild* newActor = new CacheStorageChild(this, aWorkerHolder); + PCacheStorageChild* constructedActor = + actor->SendPCacheStorageConstructor(newActor, mNamespace, *mPrincipalInfo); + + if (NS_WARN_IF(!constructedActor)) { + mStatus = NS_ERROR_UNEXPECTED; + return; } + + MOZ_DIAGNOSTIC_ASSERT(constructedActor == newActor); + mActor = newActor; } CacheStorage::CacheStorage(nsresult aFailureResult) @@ -336,8 +341,7 @@ CacheStorage::Match(JSContext* aCx, const RequestOrUSVString& aRequest, entry->mArgs = StorageMatchArgs(CacheRequest(), params, GetOpenMode()); entry->mRequest = request; - mPendingRequests.AppendElement(entry.forget()); - MaybeRunPendingRequests(); + RunRequest(Move(entry)); return promise.forget(); } @@ -361,8 +365,7 @@ CacheStorage::Has(const nsAString& aKey, ErrorResult& aRv) entry->mPromise = promise; entry->mArgs = StorageHasArgs(nsString(aKey)); - mPendingRequests.AppendElement(entry.forget()); - MaybeRunPendingRequests(); + RunRequest(Move(entry)); return promise.forget(); } @@ -386,8 +389,7 @@ CacheStorage::Open(const nsAString& aKey, ErrorResult& aRv) entry->mPromise = promise; entry->mArgs = StorageOpenArgs(nsString(aKey)); - mPendingRequests.AppendElement(entry.forget()); - MaybeRunPendingRequests(); + RunRequest(Move(entry)); return promise.forget(); } @@ -411,8 +413,7 @@ CacheStorage::Delete(const nsAString& aKey, ErrorResult& aRv) entry->mPromise = promise; entry->mArgs = StorageDeleteArgs(nsString(aKey)); - mPendingRequests.AppendElement(entry.forget()); - MaybeRunPendingRequests(); + RunRequest(Move(entry)); return promise.forget(); } @@ -436,8 +437,7 @@ CacheStorage::Keys(ErrorResult& aRv) entry->mPromise = promise; entry->mArgs = StorageKeysArgs(); - mPendingRequests.AppendElement(entry.forget()); - MaybeRunPendingRequests(); + RunRequest(Move(entry)); return promise.forget(); } @@ -498,66 +498,19 @@ CacheStorage::WrapObject(JSContext* aContext, JS::Handle aGivenProto) return mozilla::dom::CacheStorageBinding::Wrap(aContext, this, aGivenProto); } -void -CacheStorage::ActorCreated(PBackgroundChild* aActor) -{ - NS_ASSERT_OWNINGTHREAD(CacheStorage); - MOZ_DIAGNOSTIC_ASSERT(aActor); - - if (NS_WARN_IF(mWorkerHolder && mWorkerHolder->Notified())) { - ActorFailed(); - return; - } - - // WorkerHolder ownership is passed to the CacheStorageChild actor and any - // actors it may create. The WorkerHolder will keep the worker thread alive - // until the actors can gracefully shutdown. - CacheStorageChild* newActor = new CacheStorageChild(this, mWorkerHolder); - PCacheStorageChild* constructedActor = - aActor->SendPCacheStorageConstructor(newActor, mNamespace, *mPrincipalInfo); - - if (NS_WARN_IF(!constructedActor)) { - ActorFailed(); - return; - } - - mWorkerHolder = nullptr; - - MOZ_DIAGNOSTIC_ASSERT(constructedActor == newActor); - mActor = newActor; - - MaybeRunPendingRequests(); - MOZ_DIAGNOSTIC_ASSERT(mPendingRequests.IsEmpty()); -} - -void -CacheStorage::ActorFailed() -{ - NS_ASSERT_OWNINGTHREAD(CacheStorage); - MOZ_DIAGNOSTIC_ASSERT(!NS_FAILED(mStatus)); - - mStatus = NS_ERROR_UNEXPECTED; - mWorkerHolder = nullptr; - - for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) { - nsAutoPtr entry(mPendingRequests[i].forget()); - entry->mPromise->MaybeReject(NS_ERROR_UNEXPECTED); - } - mPendingRequests.Clear(); -} - void CacheStorage::DestroyInternal(CacheStorageChild* aActor) { NS_ASSERT_OWNINGTHREAD(CacheStorage); MOZ_DIAGNOSTIC_ASSERT(mActor); MOZ_DIAGNOSTIC_ASSERT(mActor == aActor); + MOZ_DIAGNOSTIC_ASSERT(!NS_FAILED(mStatus)); mActor->ClearListener(); mActor = nullptr; + mStatus = NS_ERROR_UNEXPECTED; // Note that we will never get an actor again in case another request is // made before this object is destructed. - ActorFailed(); } nsIGlobalObject* @@ -595,26 +548,24 @@ CacheStorage::~CacheStorage() } void -CacheStorage::MaybeRunPendingRequests() +CacheStorage::RunRequest(nsAutoPtr&& aEntry) { - if (!mActor) { - return; - } + MOZ_ASSERT(mActor); - for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) { + nsAutoPtr entry(Move(aEntry)); + + AutoChildOpArgs args(this, entry->mArgs, 1); + + if (entry->mRequest) { ErrorResult rv; - nsAutoPtr entry(mPendingRequests[i].forget()); - AutoChildOpArgs args(this, entry->mArgs, 1); - if (entry->mRequest) { - args.Add(entry->mRequest, IgnoreBody, IgnoreInvalidScheme, rv); - } + args.Add(entry->mRequest, IgnoreBody, IgnoreInvalidScheme, rv); if (NS_WARN_IF(rv.Failed())) { entry->mPromise->MaybeReject(rv); - continue; + return; } - mActor->ExecuteOp(mGlobal, entry->mPromise, this, args.SendAsOpArgs()); } - mPendingRequests.Clear(); + + mActor->ExecuteOp(mGlobal, entry->mPromise, this, args.SendAsOpArgs()); } OpenMode diff --git a/dom/cache/CacheStorage.h b/dom/cache/CacheStorage.h index b3f7e62c738f..2ba60dcd769a 100644 --- a/dom/cache/CacheStorage.h +++ b/dom/cache/CacheStorage.h @@ -14,7 +14,6 @@ #include "nsISupportsImpl.h" #include "nsTArray.h" #include "nsWrapperCache.h" -#include "nsIIPCBackgroundChildCreateCallback.h" class nsIGlobalObject; @@ -40,7 +39,7 @@ namespace cache { class CacheStorageChild; class CacheWorkerHolder; -class CacheStorage final : public nsIIPCBackgroundChildCreateCallback +class CacheStorage final : public nsISupports , public nsWrapperCache , public TypeUtils { @@ -79,10 +78,6 @@ public: nsISupports* GetParentObject() const; virtual JSObject* WrapObject(JSContext* aContext, JS::Handle aGivenProto) override; - // nsIIPCbackgroundChildCreateCallback methods - virtual void ActorCreated(PBackgroundChild* aActor) override; - virtual void ActorFailed() override; - // Called when CacheStorageChild actor is being destroyed void DestroyInternal(CacheStorageChild* aActor); @@ -102,7 +97,8 @@ private: explicit CacheStorage(nsresult aFailureResult); ~CacheStorage(); - void MaybeRunPendingRequests(); + struct Entry; + void RunRequest(nsAutoPtr&& aEntry); OpenMode GetOpenMode() const; @@ -110,20 +106,15 @@ private: const Namespace mNamespace; nsCOMPtr mGlobal; UniquePtr mPrincipalInfo; - RefPtr mWorkerHolder; // weak ref cleared in DestroyInternal CacheStorageChild* mActor; - struct Entry; - nsTArray> mPendingRequests; - nsresult mStatus; public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CacheStorage, - nsIIPCBackgroundChildCreateCallback) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CacheStorage) }; } // namespace cache