Bug 1170543 P1 Create separate KeepAliveTokens for service worker events and script evaluation. r=asuth
authorBen Kelly <ben@wanderview.com>
Wed, 27 Jul 2016 20:36:10 -0400
changeset 332033 d7558f1c86e28d9635b1b6e1d1982fc45da8c9cc
parent 332032 562910144a3a32a69af4957e52d250df5a83136e
child 332034 8e030b615ff4e6d1c2868c8d8c3b31e1a9bcddf4
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1170543
milestone50.0a1
Bug 1170543 P1 Create separate KeepAliveTokens for service worker events and script evaluation. r=asuth
dom/workers/ServiceWorkerPrivate.cpp
dom/workers/ServiceWorkerPrivate.h
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -146,19 +146,18 @@ ServiceWorkerPrivate::SendMessageEvent(J
                                        const Optional<Sequence<JS::Value>>& aTransferable,
                                        UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
 {
   ErrorResult rv(SpawnWorkerIfNeeded(MessageEvent, nullptr));
   if (NS_WARN_IF(rv.Failed())) {
     return rv.StealNSResult();
   }
 
-  MOZ_ASSERT(mKeepAliveToken);
   nsMainThreadPtrHandle<nsISupports> token(
-    new nsMainThreadPtrHolder<nsISupports>(mKeepAliveToken));
+    new nsMainThreadPtrHolder<nsISupports>(CreateEventKeepAliveToken()));
 
   RefPtr<PromiseNativeHandler> handler = new MessageWaitUntilHandler(token);
 
   mWorkerPrivate->PostMessageToServiceWorker(aCx, aMessage, aTransferable,
                                              Move(aClientInfo), handler,
                                              rv);
   return rv.StealNSResult();
 }
@@ -223,19 +222,19 @@ private:
 } // anonymous namespace
 
 nsresult
 ServiceWorkerPrivate::CheckScriptEvaluation(LifeCycleEventCallback* aCallback)
 {
   nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  MOZ_ASSERT(mKeepAliveToken);
+  RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<WorkerRunnable> r = new CheckScriptEvaluationWithCallback(mWorkerPrivate,
-                                                                   mKeepAliveToken,
+                                                                   token,
                                                                    aCallback);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
@@ -713,21 +712,21 @@ LifecycleEventWorkerRunnable::DispatchLi
 nsresult
 ServiceWorkerPrivate::SendLifeCycleEvent(const nsAString& aEventType,
                                          LifeCycleEventCallback* aCallback,
                                          nsIRunnable* aLoadFailure)
 {
   nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, aLoadFailure);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  MOZ_ASSERT(mKeepAliveToken);
+  RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<WorkerRunnable> r = new LifecycleEventWorkerRunnable(mWorkerPrivate,
-                                                                mKeepAliveToken,
-                                                                aEventType,
-                                                                aCallback);
+                                                              token,
+                                                              aEventType,
+                                                              aCallback);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 #ifndef MOZ_SIMPLEPUSH
@@ -904,23 +903,23 @@ ServiceWorkerPrivate::SendPushEvent(cons
                                     ServiceWorkerRegistrationInfo* aRegistration)
 {
 #ifdef MOZ_SIMPLEPUSH
   return NS_ERROR_NOT_AVAILABLE;
 #else
   nsresult rv = SpawnWorkerIfNeeded(PushEvent, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  MOZ_ASSERT(mKeepAliveToken);
+  RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
 
   nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> regInfo(
     new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(aRegistration, false));
 
   RefPtr<WorkerRunnable> r = new SendPushEventRunnable(mWorkerPrivate,
-                                                       mKeepAliveToken,
+                                                       token,
                                                        aMessageId,
                                                        aData,
                                                        regInfo);
 
   if (mInfo->State() == ServiceWorkerState::Activating) {
     mPendingFunctionalEvents.AppendElement(r.forget());
     return NS_OK;
   }
@@ -939,19 +938,19 @@ nsresult
 ServiceWorkerPrivate::SendPushSubscriptionChangeEvent()
 {
 #ifdef MOZ_SIMPLEPUSH
   return NS_ERROR_NOT_AVAILABLE;
 #else
   nsresult rv = SpawnWorkerIfNeeded(PushSubscriptionChangeEvent, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  MOZ_ASSERT(mKeepAliveToken);
+  RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<WorkerRunnable> r =
-    new SendPushSubscriptionChangeEventRunnable(mWorkerPrivate, mKeepAliveToken);
+    new SendPushSubscriptionChangeEventRunnable(mWorkerPrivate, token);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 #endif // MOZ_SIMPLEPUSH
 }
 
@@ -1229,18 +1228,20 @@ ServiceWorkerPrivate::SendNotificationEv
   } else {
     MOZ_ASSERT_UNREACHABLE("Invalid notification event name");
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = SpawnWorkerIfNeeded(why, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
+
   RefPtr<WorkerRunnable> r =
-    new SendNotificationEventRunnable(mWorkerPrivate, mKeepAliveToken,
+    new SendNotificationEventRunnable(mWorkerPrivate, token,
                                       aEventName, aID, aTitle, aDir, aLang,
                                       aBody, aTag, aIcon, aData, aBehavior,
                                       aScope);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
@@ -1631,18 +1632,20 @@ ServiceWorkerPrivate::SendFetchEvent(nsI
   MOZ_ASSERT(swm);
 
   RefPtr<ServiceWorkerRegistrationInfo> registration =
     swm->GetRegistration(mInfo->GetPrincipal(), mInfo->Scope());
 
   nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> regInfo(
     new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(registration, false));
 
+  RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
+
   RefPtr<FetchEventRunnable> r =
-    new FetchEventRunnable(mWorkerPrivate, mKeepAliveToken, handle,
+    new FetchEventRunnable(mWorkerPrivate, token, handle,
                            mInfo->ScriptSpec(), regInfo,
                            aDocumentId, aIsReload);
   rv = r->Init();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (mInfo->State() == ServiceWorkerState::Activating) {
@@ -1989,9 +1992,19 @@ ServiceWorkerPrivate::ReleaseToken()
 
   MOZ_ASSERT(mTokenCount > 0);
   --mTokenCount;
   if (!mTokenCount) {
     TerminateWorker();
   }
 }
 
+already_AddRefed<KeepAliveToken>
+ServiceWorkerPrivate::CreateEventKeepAliveToken()
+{
+  AssertIsOnMainThread();
+  MOZ_ASSERT(mWorkerPrivate);
+  MOZ_ASSERT(mKeepAliveToken);
+  RefPtr<KeepAliveToken> ref = new KeepAliveToken(this);
+  return ref.forget();
+}
+
 END_WORKERS_NAMESPACE
--- a/dom/workers/ServiceWorkerPrivate.h
+++ b/dom/workers/ServiceWorkerPrivate.h
@@ -181,16 +181,19 @@ private:
   // if the script loader failed for some reason, but can be null.
   nsresult
   SpawnWorkerIfNeeded(WakeUpReason aWhy,
                       nsIRunnable* aLoadFailedRunnable,
                       nsILoadGroup* aLoadGroup = nullptr);
 
   ~ServiceWorkerPrivate();
 
+  already_AddRefed<KeepAliveToken>
+  CreateEventKeepAliveToken();
+
   // The info object owns us. It is possible to outlive it for a brief period
   // of time if there are pending waitUntil promises, in which case it
   // will be null and |SpawnWorkerIfNeeded| will always fail.
   ServiceWorkerInfo* MOZ_NON_OWNING_REF mInfo;
 
   // The WorkerPrivate object can only be closed by this class or by the
   // RuntimeService class if gecko is shutting down. Closing the worker
   // multiple times is OK, since the second attempt will be a no-op.