From 80b1443c29c901b4f15e3c9d39a1f86d2e6a6cc0 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 5 Jul 2018 13:13:48 -0400 Subject: [PATCH] Bug 1472005 Don't resolve ready promise until the registration has reached the right state version. r=mrbkap --- dom/serviceworkers/ServiceWorkerContainer.cpp | 9 ++++++- .../ServiceWorkerRegistration.cpp | 24 +++++++++++++++++++ .../ServiceWorkerRegistration.h | 17 +++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dom/serviceworkers/ServiceWorkerContainer.cpp b/dom/serviceworkers/ServiceWorkerContainer.cpp index 1c51ac8303c7..9d5cc8af2403 100644 --- a/dom/serviceworkers/ServiceWorkerContainer.cpp +++ b/dom/serviceworkers/ServiceWorkerContainer.cpp @@ -544,7 +544,14 @@ ServiceWorkerContainer::GetReady(ErrorResult& aRv) RefPtr reg = global->GetOrCreateServiceWorkerRegistration(aDescriptor); NS_ENSURE_TRUE_VOID(reg); - outer->MaybeResolve(reg); + + // Don't resolve the ready promise until the registration has + // reached the right version. This ensures that the active + // worker property is set correctly on the registration. + reg->WhenVersionReached(aDescriptor.Version(), + [outer, reg] (bool aResult) { + outer->MaybeResolve(reg); + }); }, [self, outer] (ErrorResult& aRv) { outer->MaybeReject(aRv); }); diff --git a/dom/serviceworkers/ServiceWorkerRegistration.cpp b/dom/serviceworkers/ServiceWorkerRegistration.cpp index 1d306444b0d6..2dc3ad469e69 100644 --- a/dom/serviceworkers/ServiceWorkerRegistration.cpp +++ b/dom/serviceworkers/ServiceWorkerRegistration.cpp @@ -158,6 +158,17 @@ ServiceWorkerRegistration::UpdateState(const ServiceWorkerRegistrationDescriptor UpdateStateInternal(aDescriptor.GetInstalling(), aDescriptor.GetWaiting(), aDescriptor.GetActive()); + + nsTArray> callbackList; + mVersionCallbackList.SwapElements(callbackList); + for (auto& cb : callbackList) { + if (cb->mVersion > mDescriptor.Version()) { + mVersionCallbackList.AppendElement(std::move(cb)); + continue; + } + + cb->mFunc(cb->mVersion == mDescriptor.Version()); + } } bool @@ -343,6 +354,19 @@ ServiceWorkerRegistration::Descriptor() const return mDescriptor; } +void +ServiceWorkerRegistration::WhenVersionReached(uint64_t aVersion, + ServiceWorkerBoolCallback&& aCallback) +{ + if (aVersion <= mDescriptor.Version()) { + aCallback(aVersion == mDescriptor.Version()); + return; + } + + mVersionCallbackList.AppendElement( + MakeUnique(aVersion, std::move(aCallback))); +} + void ServiceWorkerRegistration::MaybeScheduleUpdateFound(const Maybe& aInstallingDescriptor) { diff --git a/dom/serviceworkers/ServiceWorkerRegistration.h b/dom/serviceworkers/ServiceWorkerRegistration.h index 54a4f92b224e..29b038661e03 100644 --- a/dom/serviceworkers/ServiceWorkerRegistration.h +++ b/dom/serviceworkers/ServiceWorkerRegistration.h @@ -119,6 +119,9 @@ public: const ServiceWorkerRegistrationDescriptor& Descriptor() const; + void + WhenVersionReached(uint64_t aVersion, ServiceWorkerBoolCallback&& aCallback); + private: ServiceWorkerRegistration(nsIGlobalObject* aGlobal, const ServiceWorkerRegistrationDescriptor& aDescriptor, @@ -148,6 +151,20 @@ private: RefPtr mActiveWorker; RefPtr mPushManager; + struct VersionCallback + { + uint64_t mVersion; + ServiceWorkerBoolCallback mFunc; + + VersionCallback(uint64_t aVersion, ServiceWorkerBoolCallback&& aFunc) + : mVersion(aVersion) + , mFunc(std::move(aFunc)) + { + MOZ_DIAGNOSTIC_ASSERT(mFunc); + } + }; + nsTArray> mVersionCallbackList; + uint64_t mScheduledUpdateFoundId; uint64_t mDispatchedUpdateFoundId; uint32_t mPendingUpdatePromises;