From 7ab3bc5f8bf1a44c5e8fc8c8277eb19c00ce1e11 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Tue, 17 Oct 2017 13:38:54 -0700 Subject: [PATCH] Bug 1204254 P3 Move logic into StartFinish() runnable separate from FinishRunnable() in ServiceWorkerEvents. r=asuth --- dom/workers/ServiceWorkerEvents.cpp | 91 ++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index 4e9b2a59d864..89a902b5cb02 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -164,7 +164,7 @@ FetchEvent::Constructor(const GlobalObject& aGlobal, namespace { -class FinishResponse final : public Runnable +class StartResponse final : public Runnable { nsMainThreadPtrHandle mChannel; RefPtr mInternalResponse; @@ -173,12 +173,12 @@ class FinishResponse final : public Runnable const nsCString mResponseURLSpec; public: - FinishResponse(nsMainThreadPtrHandle& aChannel, - InternalResponse* aInternalResponse, - const ChannelInfo& aWorkerChannelInfo, - const nsACString& aScriptSpec, - const nsACString& aResponseURLSpec) - : Runnable("dom::workers::FinishResponse") + StartResponse(nsMainThreadPtrHandle& aChannel, + InternalResponse* aInternalResponse, + const ChannelInfo& aWorkerChannelInfo, + const nsACString& aScriptSpec, + const nsACString& aResponseURLSpec) + : Runnable("dom::workers::StartResponse") , mChannel(aChannel) , mInternalResponse(aInternalResponse) , mWorkerChannelInfo(aWorkerChannelInfo) @@ -239,24 +239,9 @@ public: return NS_OK; } - rv = mChannel->FinishSynthesizedResponse(); - if (NS_WARN_IF(NS_FAILED(rv))) { - mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED); - return NS_OK; - } - - TimeStamp timeStamp = TimeStamp::Now(); - mChannel->SetHandleFetchEventEnd(timeStamp); - mChannel->SetFinishSynthesizedResponseEnd(timeStamp); - mChannel->SaveTimeStamps(); - - nsCOMPtr obsService = services::GetObserverService(); - if (obsService) { - obsService->NotifyObservers(underlyingChannel, "service-worker-synthesized-response", nullptr); - } - return rv; } + bool CSPPermitsResponse(nsILoadInfo* aLoadInfo) { AssertIsOnMainThread(); @@ -281,6 +266,47 @@ public: } }; +class FinishResponse final : public Runnable +{ + nsMainThreadPtrHandle mChannel; + +public: + explicit FinishResponse(nsMainThreadPtrHandle& aChannel) + : Runnable("dom::workers::FinishResponse") + , mChannel(aChannel) + { + } + + NS_IMETHOD + Run() override + { + AssertIsOnMainThread(); + + nsresult rv = mChannel->FinishSynthesizedResponse(); + if (NS_WARN_IF(NS_FAILED(rv))) { + mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED); + return NS_OK; + } + + TimeStamp timeStamp = TimeStamp::Now(); + mChannel->SetHandleFetchEventEnd(timeStamp); + mChannel->SetFinishSynthesizedResponseEnd(timeStamp); + mChannel->SaveTimeStamps(); + + nsCOMPtr obsService = services::GetObserverService(); + if (obsService) { + nsCOMPtr underlyingChannel; + nsresult rv = mChannel->GetChannel(getter_AddRefs(underlyingChannel)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(underlyingChannel, NS_ERROR_UNEXPECTED); + + obsService->NotifyObservers(underlyingChannel, "service-worker-synthesized-response", nullptr); + } + + return rv; + } +}; + class RespondWithHandler final : public PromiseNativeHandler { nsMainThreadPtrHandle mInterceptedChannel; @@ -405,12 +431,21 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus) data->mRegistration, NS_ERROR_INTERCEPTION_FAILED); } else { - event = new FinishResponse(data->mInterceptedChannel, - data->mInternalResponse, - data->mWorkerChannelInfo, - data->mScriptSpec, - data->mResponseURLSpec); + event = new StartResponse(data->mInterceptedChannel, + data->mInternalResponse, + data->mWorkerChannelInfo, + data->mScriptSpec, + data->mResponseURLSpec); + WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); + if (worker) { + MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(event.forget())); + } else { + MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event.forget())); + } + + event = new FinishResponse(data->mInterceptedChannel); } + // In theory this can happen after the worker thread is terminated. WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); if (worker) {