From 0b450a3def17997a82d66370378cf18870553f3d Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Thu, 28 Sep 2023 17:35:26 -0500 Subject: [PATCH] Issue #1442 - Part 12b - Allow idle worker shutdown while Cache/CacheStorage DOM objects exist, but block it during Cache operation. https://bugzilla.mozilla.org/show_bug.cgi?id=1362444 Pre-requisite for Part 13. --- dom/cache/CacheOpChild.cpp | 12 ++++++++++-- dom/cache/CacheStorage.cpp | 3 ++- dom/cache/CacheWorkerHolder.cpp | 31 +++++++++++++++++++++++++++---- dom/cache/CacheWorkerHolder.h | 8 ++++++-- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/dom/cache/CacheOpChild.cpp b/dom/cache/CacheOpChild.cpp index 492c205ffc..9dc8997c26 100644 --- a/dom/cache/CacheOpChild.cpp +++ b/dom/cache/CacheOpChild.cpp @@ -74,7 +74,11 @@ CacheOpChild::CacheOpChild(CacheWorkerHolder* aWorkerHolder, MOZ_DIAGNOSTIC_ASSERT(mPromise); MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerHolder); - SetWorkerHolder(aWorkerHolder); + RefPtr workerHolder = + CacheWorkerHolder::PreferBehavior(aWorkerHolder, + CacheWorkerHolder::PreventIdleShutdownStart); + + SetWorkerHolder(workerHolder); } CacheOpChild::~CacheOpChild() @@ -165,7 +169,11 @@ CacheOpChild::Recv__delete__(const ErrorResult& aRv, break; } - actor->SetWorkerHolder(GetWorkerHolder()); + RefPtr workerHolder = + CacheWorkerHolder::PreferBehavior(GetWorkerHolder(), + CacheWorkerHolder::AllowIdleShutdownStart); + + actor->SetWorkerHolder(workerHolder); RefPtr cache = new Cache(mGlobal, actor); mPromise->MaybeResolve(cache); break; diff --git a/dom/cache/CacheStorage.cpp b/dom/cache/CacheStorage.cpp index 2dae0b157d..3ace28c156 100644 --- a/dom/cache/CacheStorage.cpp +++ b/dom/cache/CacheStorage.cpp @@ -204,7 +204,8 @@ CacheStorage::CreateOnWorker(Namespace aNamespace, nsIGlobalObject* aGlobal, } RefPtr workerHolder = - CacheWorkerHolder::Create(aWorkerPrivate); + CacheWorkerHolder::Create(aWorkerPrivate, + CacheWorkerHolder::AllowIdleShutdownStart); if (!workerHolder) { NS_WARNING("Worker thread is shutting down."); aRv.Throw(NS_ERROR_FAILURE); diff --git a/dom/cache/CacheWorkerHolder.cpp b/dom/cache/CacheWorkerHolder.cpp index 4ac97cbcab..1fd78553ee 100644 --- a/dom/cache/CacheWorkerHolder.cpp +++ b/dom/cache/CacheWorkerHolder.cpp @@ -18,11 +18,11 @@ using mozilla::dom::workers::WorkerPrivate; // static already_AddRefed -CacheWorkerHolder::Create(WorkerPrivate* aWorkerPrivate) +CacheWorkerHolder::Create(WorkerPrivate* aWorkerPrivate, Behavior aBehavior) { MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate); - RefPtr workerHolder = new CacheWorkerHolder(); + RefPtr workerHolder = new CacheWorkerHolder(aBehavior); if (NS_WARN_IF(!workerHolder->HoldWorker(aWorkerPrivate, Terminating))) { return nullptr; } @@ -30,6 +30,28 @@ CacheWorkerHolder::Create(WorkerPrivate* aWorkerPrivate) return workerHolder.forget(); } +// static +already_AddRefed +CacheWorkerHolder::PreferBehavior(CacheWorkerHolder* aCurrentHolder, + Behavior aBehavior) +{ + if (!aCurrentHolder) { + return nullptr; + } + + RefPtr orig = aCurrentHolder; + if (orig->GetBehavior() == aBehavior) { + return orig.forget(); + } + + RefPtr replace = Create(orig->mWorkerPrivate, aBehavior); + if (!replace) { + return orig.forget(); + } + + return replace.forget(); +} + void CacheWorkerHolder::AddActor(ActorChild* aActor) { @@ -88,8 +110,9 @@ CacheWorkerHolder::Notify(Status aStatus) return true; } -CacheWorkerHolder::CacheWorkerHolder() - : mNotified(false) +CacheWorkerHolder::CacheWorkerHolder(Behavior aBehavior) + : WorkerHolder(aBehavior) + , mNotified(false) { } diff --git a/dom/cache/CacheWorkerHolder.h b/dom/cache/CacheWorkerHolder.h index 9eed7e2b6a..7e4c55f839 100644 --- a/dom/cache/CacheWorkerHolder.h +++ b/dom/cache/CacheWorkerHolder.h @@ -25,7 +25,11 @@ class CacheWorkerHolder final : public workers::WorkerHolder { public: static already_AddRefed - Create(workers::WorkerPrivate* aWorkerPrivate); + Create(workers::WorkerPrivate* aWorkerPrivate, + Behavior aBehavior); + + static already_AddRefed + PreferBehavior(CacheWorkerHolder* aCurrentHolder, Behavior aBehavior); void AddActor(ActorChild* aActor); void RemoveActor(ActorChild* aActor); @@ -36,7 +40,7 @@ public: virtual bool Notify(workers::Status aStatus) override; private: - CacheWorkerHolder(); + explicit CacheWorkerHolder(Behavior aBehavior); ~CacheWorkerHolder(); nsTArray mActorList;