From 7358d7c9773dde2b1e0a280bb51abd15417288dc Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Wed, 6 Apr 2016 13:27:22 -0700 Subject: [PATCH] Bug 1256428 P6 Use ServiceWorkerJobQueue2 and new job classes in ServiceWorkerManager. r=jdm --- dom/workers/ServiceWorkerManager.cpp | 212 +++++++++++++++++++-------- dom/workers/ServiceWorkerManager.h | 4 +- 2 files changed, 152 insertions(+), 64 deletions(-) diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index b277634bfe53..20ef5a8bfb24 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -64,12 +64,16 @@ #include "ServiceWorker.h" #include "ServiceWorkerClient.h" #include "ServiceWorkerContainer.h" +#include "ServiceWorkerJobQueue.h" #include "ServiceWorkerManagerChild.h" #include "ServiceWorkerPrivate.h" +#include "ServiceWorkerRegisterJob.h" #include "ServiceWorkerRegistrar.h" #include "ServiceWorkerRegistration.h" #include "ServiceWorkerScriptCache.h" #include "ServiceWorkerEvents.h" +#include "ServiceWorkerUnregisterJob.h" +#include "ServiceWorkerUpdateJob.h" #include "SharedWorker.h" #include "WorkerInlines.h" #include "WorkerPrivate.h" @@ -145,7 +149,7 @@ struct ServiceWorkerManager::RegistrationDataPerPrincipal final nsRefPtrHashtable mInfos; // Maps scopes to job queues. - nsClassHashtable mJobQueues; + nsRefPtrHashtable mJobQueues; // Map scopes to scheduled update timers. nsInterfaceHashtable mUpdateTimers; @@ -709,7 +713,7 @@ public: } }; -class ServiceWorkerResolveWindowPromiseOnUpdateCallback final : public ServiceWorkerUpdateFinishCallback +class ServiceWorkerResolveWindowPromiseOnUpdateCallback final : public ServiceWorkerJob2::Callback { RefPtr mWindow; // The promise "returned" by the call to Update up to @@ -719,6 +723,22 @@ class ServiceWorkerResolveWindowPromiseOnUpdateCallback final : public ServiceWo ~ServiceWorkerResolveWindowPromiseOnUpdateCallback() {} + virtual void + JobFinished(ServiceWorkerJob2* aJob, ErrorResult& aStatus) override + { + AssertIsOnMainThread(); + MOZ_ASSERT(aJob); + + if (aStatus.Failed()) { + mPromise->MaybeReject(aStatus); + return; + } + + RefPtr swr = + mWindow->GetServiceWorkerRegistration(NS_ConvertUTF8toUTF16(aJob->GetScope())); + mPromise->MaybeResolve(swr); + } + public: ServiceWorkerResolveWindowPromiseOnUpdateCallback(nsPIDOMWindowInner* aWindow, Promise* aPromise) @@ -726,19 +746,7 @@ public: , mPromise(aPromise) {} - void - UpdateSucceeded(ServiceWorkerRegistrationInfo* aInfo) override - { - RefPtr swr = - mWindow->GetServiceWorkerRegistration(NS_ConvertUTF8toUTF16(aInfo->mScope)); - mPromise->MaybeResolve(swr); - } - - void - UpdateFailed(ErrorResult& aStatus) override - { - mPromise->MaybeReject(aStatus); - } + NS_INLINE_DECL_REFCOUNTING(ServiceWorkerResolveWindowPromiseOnUpdateCallback, override) }; class ContinueUpdateRunnable final : public LifeCycleEventCallback @@ -1828,8 +1836,8 @@ ServiceWorkerManager::Register(mozIDOMWindow* aWindow, AddRegisteringDocument(cleanedScope, doc); - ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(scopeKey, cleanedScope); - MOZ_ASSERT(queue); + RefPtr queue = GetOrCreateJobQueue(scopeKey, + cleanedScope); RefPtr cb = new ServiceWorkerResolveWindowPromiseOnUpdateCallback(window, promise); @@ -1845,10 +1853,11 @@ ServiceWorkerManager::Register(mozIDOMWindow* aWindow, nsCOMPtr loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID); MOZ_ALWAYS_SUCCEEDS(loadGroup->SetNotificationCallbacks(ir)); - RefPtr job = - new ServiceWorkerRegisterJob(queue, documentPrincipal, cleanedScope, spec, - cb, loadGroup); - queue->Append(job); + RefPtr job = + new ServiceWorkerRegisterJob2(documentPrincipal, cleanedScope, spec, + loadGroup); + job->AppendResultCallback(cb); + queue->ScheduleJob(job); AssertIsOnMainThread(); Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REGISTRATIONS, 1); @@ -2588,6 +2597,46 @@ private: } }; +namespace { + +class UnregisterJobCallback final : public ServiceWorkerJob2::Callback +{ + nsCOMPtr mCallback; + + ~UnregisterJobCallback() + { + } + +public: + explicit UnregisterJobCallback(nsIServiceWorkerUnregisterCallback* aCallback) + : mCallback(aCallback) + { + AssertIsOnMainThread(); + MOZ_ASSERT(mCallback); + } + + void + JobFinished(ServiceWorkerJob2* aJob, ErrorResult& aStatus) + { + AssertIsOnMainThread(); + MOZ_ASSERT(aJob); + + if (aStatus.Failed()) { + mCallback->UnregisterFailed(); + return; + } + + MOZ_ASSERT(aJob->GetType() == ServiceWorkerJob2::Type::Unregister); + RefPtr unregisterJob = + static_cast(aJob); + mCallback->UnregisterSucceeded(unregisterJob->GetResult()); + } + + NS_INLINE_DECL_REFCOUNTING(UnregisterJobCallback) +}; + +} // anonymous namespace + NS_IMETHODIMP ServiceWorkerManager::Unregister(nsIPrincipal* aPrincipal, nsIServiceWorkerUnregisterCallback* aCallback, @@ -2618,18 +2667,17 @@ ServiceWorkerManager::Unregister(nsIPrincipal* aPrincipal, } NS_ConvertUTF16toUTF8 scope(aScope); - ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(scopeKey, scope); - MOZ_ASSERT(queue); + RefPtr queue = GetOrCreateJobQueue(scopeKey, scope); - RefPtr job = - new ServiceWorkerUnregisterJob(queue, scope, aCallback, aPrincipal); + RefPtr job = + new ServiceWorkerUnregisterJob2(aPrincipal, scope, true /* send to parent */); - if (mActor) { - queue->Append(job); - return NS_OK; + if (aCallback) { + RefPtr cb = new UnregisterJobCallback(aCallback); + job->AppendResultCallback(cb); } - AppendPendingOperation(queue, job); + queue->ScheduleJob(job); return NS_OK; } @@ -2659,22 +2707,17 @@ ServiceWorkerManager::NotifyUnregister(nsIPrincipal* aPrincipal, } NS_ConvertUTF16toUTF8 scope(aScope); - ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(scopeKey, scope); - MOZ_ASSERT(queue); + RefPtr queue = GetOrCreateJobQueue(scopeKey, scope); - RefPtr job = - new ServiceWorkerUnregisterJob(queue, scope, nullptr, aPrincipal, false); + RefPtr job = + new ServiceWorkerUnregisterJob2(aPrincipal, scope, + false /* send to parent */); - if (mActor) { - queue->Append(job); - return NS_OK; - } - - AppendPendingOperation(queue, job); + queue->ScheduleJob(job); return NS_OK; } -ServiceWorkerJobQueue* +already_AddRefed ServiceWorkerManager::GetOrCreateJobQueue(const nsACString& aKey, const nsACString& aScope) { @@ -2685,13 +2728,14 @@ ServiceWorkerManager::GetOrCreateJobQueue(const nsACString& aKey, mRegistrationInfos.Put(aKey, data); } - ServiceWorkerJobQueue* queue; - if (!data->mJobQueues.Get(aScope, &queue)) { - queue = new ServiceWorkerJobQueue(aKey); - data->mJobQueues.Put(aScope, queue); + RefPtr queue; + if (!data->mJobQueues.Get(aScope, getter_AddRefs(queue))) { + RefPtr newQueue = new ServiceWorkerJobQueue2(); + queue = newQueue; + data->mJobQueues.Put(aScope, newQueue.forget()); } - return queue; + return queue.forget(); } /* static */ @@ -3969,16 +4013,56 @@ ServiceWorkerManager::SoftUpdate(const PrincipalOriginAttributes& aOriginAttribu // TODO(catalinb): We don't implement the force bypass cache flag. // See: https://github.com/slightlyoff/ServiceWorker/issues/759 if (!registration->mUpdating) { - ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(scopeKey, aScope); - MOZ_ASSERT(queue); + RefPtr queue = GetOrCreateJobQueue(scopeKey, + aScope); - RefPtr job = - new ServiceWorkerRegisterJob(queue, principal, registration->mScope, - newest->ScriptSpec(), nullptr); - queue->Append(job); + RefPtr job = + new ServiceWorkerUpdateJob2(principal, registration->mScope, + newest->ScriptSpec(), nullptr); + queue->ScheduleJob(job); } } +namespace { + +class UpdateJobCallback final : public ServiceWorkerJob2::Callback +{ + RefPtr mCallback; + + ~UpdateJobCallback() + { + } + +public: + explicit UpdateJobCallback(ServiceWorkerUpdateFinishCallback* aCallback) + : mCallback(aCallback) + { + AssertIsOnMainThread(); + MOZ_ASSERT(mCallback); + } + + void + JobFinished(ServiceWorkerJob2* aJob, ErrorResult& aStatus) + { + AssertIsOnMainThread(); + MOZ_ASSERT(aJob); + + if (aStatus.Failed()) { + mCallback->UpdateFailed(aStatus); + return; + } + + MOZ_ASSERT(aJob->GetType() == ServiceWorkerJob2::Type::Update); + RefPtr updateJob = + static_cast(aJob); + RefPtr reg = updateJob->GetRegistration(); + mCallback->UpdateSucceeded(reg); + } + + NS_INLINE_DECL_REFCOUNTING(UpdateJobCallback) +}; +} // anonymous namespace + void ServiceWorkerManager::Update(nsIPrincipal* aPrincipal, const nsACString& aScope, @@ -4013,16 +4097,18 @@ ServiceWorkerManager::Update(nsIPrincipal* aPrincipal, return; } - ServiceWorkerJobQueue* queue = - GetOrCreateJobQueue(scopeKey, aScope); - MOZ_ASSERT(queue); + RefPtr queue = GetOrCreateJobQueue(scopeKey, aScope); // "Invoke Update algorithm, or its equivalent, with client, registration as // its argument." - RefPtr job = - new ServiceWorkerRegisterJob(queue, aPrincipal, registration->mScope, - newest->ScriptSpec(), aCallback); - queue->Append(job); + RefPtr job = + new ServiceWorkerUpdateJob2(aPrincipal, registration->mScope, + newest->ScriptSpec(), nullptr); + + RefPtr cb = new UpdateJobCallback(aCallback); + job->AppendResultCallback(cb); + + queue->ScheduleJob(job); } namespace { @@ -4472,10 +4558,10 @@ ServiceWorkerManager::ForceUnregister(RegistrationDataPerPrincipal* aRegistratio MOZ_ASSERT(aRegistrationData); MOZ_ASSERT(aRegistration); - ServiceWorkerJobQueue* queue; - aRegistrationData->mJobQueues.Get(aRegistration->mScope, &queue); + RefPtr queue; + aRegistrationData->mJobQueues.Get(aRegistration->mScope, getter_AddRefs(queue)); if (queue) { - queue->CancelJobs(); + queue->CancelAll(); } nsCOMPtr timer = @@ -4787,8 +4873,8 @@ ServiceWorkerManager::Observe(nsISupports* aSubject, it1.UserData()->mUpdateTimers.Clear(); for (auto it2 = it1.UserData()->mJobQueues.Iter(); !it2.Done(); it2.Next()) { - ServiceWorkerJobQueue* queue = it2.UserData(); - queue->CancelJobs(); + RefPtr queue = it2.UserData(); + queue->CancelAll(); } it1.UserData()->mJobQueues.Clear(); } diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index bfaa765cea2d..77c5ee06d679 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -49,6 +49,7 @@ class ServiceWorkerClientInfo; class ServiceWorkerInfo; class ServiceWorkerJob; class ServiceWorkerJobQueue; +class ServiceWorkerJobQueue2; class ServiceWorkerManagerChild; class ServiceWorkerPrivate; @@ -515,7 +516,7 @@ private: void Init(); - ServiceWorkerJobQueue* + already_AddRefed GetOrCreateJobQueue(const nsACString& aOriginSuffix, const nsACString& aScope); @@ -630,6 +631,7 @@ private: }; void AppendPendingOperation(nsIRunnable* aRunnable); + // TODO: remove this void AppendPendingOperation(ServiceWorkerJobQueue* aQueue, ServiceWorkerJob* aJob);