Bug 1469566 - Port 2 ServiceWorker WorkerHolders to WorkerRef - part 2, r=bkelly
☠☠ backed out by c9bad496f81b ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 19 Jun 2018 13:08:12 -0400
changeset 423051 258a2da40ef0bdbd538eddb4680fc1b511875b88
parent 423050 85d2aec2f4b6ebd72a8a87af20575b678142023f
child 423052 86754e309cfee33291f4b732fc4e28f76db727cb
push id65342
push userapavel@mozilla.com
push dateWed, 20 Jun 2018 11:30:38 +0000
treeherderautoland@dadc58a65c2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1469566
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1469566 - Port 2 ServiceWorker WorkerHolders to WorkerRef - part 2, r=bkelly
dom/serviceworkers/ServiceWorkerPrivate.cpp
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -250,29 +250,27 @@ enum ExtendableEventResult {
 class ExtendableEventCallback {
 public:
   virtual void
   FinishedWithResult(ExtendableEventResult aResult) = 0;
 
   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
 };
 
-class KeepAliveHandler final : public WorkerHolder
-                             , public ExtendableEvent::ExtensionsHandler
+class KeepAliveHandler final : public ExtendableEvent::ExtensionsHandler
                              , public PromiseNativeHandler
 {
   // This class manages lifetime extensions added by calling WaitUntil()
   // or RespondWith(). We allow new extensions as long as we still hold
   // |mKeepAliveToken|. Once the last promise was settled, we queue a microtask
   // which releases the token and prevents further extensions. By doing this,
   // we give other pending microtasks a chance to continue adding extensions.
 
+  RefPtr<StrongWorkerRef> mWorkerRef;
   nsMainThreadPtrHandle<KeepAliveToken> mKeepAliveToken;
-  WorkerPrivate* MOZ_NON_OWNING_REF mWorkerPrivate;
-  bool mWorkerHolderAdded;
 
   // We start holding a self reference when the first extension promise is
   // added. As far as I can tell, the only case where this is useful is when
   // we're waiting indefinitely on a promise that's no longer reachable
   // and will never be settled.
   // The cycle is broken when the last promise was settled or when the
   // worker is shutting down.
   RefPtr<KeepAliveHandler> mSelfRef;
@@ -286,36 +284,42 @@ class KeepAliveHandler final : public Wo
   // any of them were rejected.
   bool mRejected;
 
 public:
   NS_DECL_ISUPPORTS
 
   explicit KeepAliveHandler(const nsMainThreadPtrHandle<KeepAliveToken>& aKeepAliveToken,
                             ExtendableEventCallback* aCallback)
-    : WorkerHolder("KeepAliveHolder")
-    , mKeepAliveToken(aKeepAliveToken)
-    , mWorkerPrivate(GetCurrentThreadWorkerPrivate())
-    , mWorkerHolderAdded(false)
+    : mKeepAliveToken(aKeepAliveToken)
     , mCallback(aCallback)
     , mPendingPromisesCount(0)
     , mRejected(false)
   {
     MOZ_ASSERT(mKeepAliveToken);
-    MOZ_ASSERT(mWorkerPrivate);
   }
 
   bool
-  UseWorkerHolder()
+  Init()
   {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(!mWorkerHolderAdded);
-    mWorkerHolderAdded = HoldWorker(mWorkerPrivate, Terminating);
-    return mWorkerHolderAdded;
+    MOZ_ASSERT(IsCurrentThreadRunningWorker());
+
+    RefPtr<KeepAliveHandler> self = this;
+    mWorkerRef =
+      StrongWorkerRef::Create(GetCurrentThreadWorkerPrivate(),
+                              "KeepAliveHandler",
+                              [self]() {
+        self->MaybeCleanup();
+      });
+
+    if (NS_WARN_IF(!mWorkerRef)) {
+      return false;
+    }
+
+    return true;
   }
 
   bool
   WaitOnPromise(Promise& aPromise) override
   {
     if (!mKeepAliveToken) {
       MOZ_ASSERT(!mSelfRef, "We shouldn't be holding a self reference!");
       return false;
@@ -338,34 +342,20 @@ public:
   }
 
   void
   RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
   {
     RemovePromise(Rejected);
   }
 
-  bool
-  Notify(WorkerStatus aStatus) override
-  {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    if (aStatus < Terminating) {
-      return true;
-    }
-
-    MaybeCleanup();
-    return true;
-  }
-
   void
   MaybeDone()
   {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
+    MOZ_ASSERT(IsCurrentThreadRunningWorker());
 
     if (mPendingPromisesCount || !mKeepAliveToken) {
       return;
     }
     if (mCallback) {
       mCallback->FinishedWithResult(mRejected ? Rejected : Resolved);
     }
 
@@ -376,25 +366,23 @@ private:
   ~KeepAliveHandler()
   {
     MaybeCleanup();
   }
 
   void
   MaybeCleanup()
   {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
+    MOZ_ASSERT(IsCurrentThreadRunningWorker());
+
     if (!mKeepAliveToken) {
       return;
     }
-    if (mWorkerHolderAdded) {
-      ReleaseWorker();
-    }
 
+    mWorkerRef = nullptr;
     mKeepAliveToken = nullptr;
     mSelfRef = nullptr;
   }
 
   class MaybeDoneRunner : public MicroTaskRunnable
   {
   public:
     explicit MaybeDoneRunner(KeepAliveHandler* aHandler) : mHandler(aHandler) {}
@@ -404,18 +392,17 @@ private:
     }
 
     RefPtr<KeepAliveHandler> mHandler;
   };
 
   void
   RemovePromise(ExtendableEventResult aResult)
   {
-    MOZ_ASSERT(mWorkerPrivate);
-    mWorkerPrivate->AssertIsOnWorkerThread();
+    MOZ_ASSERT(IsCurrentThreadRunningWorker());
     MOZ_DIAGNOSTIC_ASSERT(mPendingPromisesCount > 0);
 
     // Note: mSelfRef and mKeepAliveToken can be nullptr here
     //       if MaybeCleanup() was called just before a promise
     //       settled.  This can happen, for example, if the
     //       worker thread is being terminated for running too
     //       long, browser shutdown, etc.
 
@@ -491,17 +478,17 @@ public:
   {
     MOZ_ASSERT(aWorkerScope);
     MOZ_ASSERT(aEvent);
     nsCOMPtr<nsIGlobalObject> sgo = aWorkerScope;
     WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
 
     RefPtr<KeepAliveHandler> keepAliveHandler =
       new KeepAliveHandler(mKeepAliveToken, aCallback);
-    if (NS_WARN_IF(!keepAliveHandler->UseWorkerHolder())) {
+    if (NS_WARN_IF(!keepAliveHandler->Init())) {
       return NS_ERROR_FAILURE;
     }
 
     // This must always be set *before* dispatching the event, otherwise
     // waitUntil calls will fail.
     aEvent->SetKeepAliveHandler(keepAliveHandler);
 
     ErrorResult result;