Backed out changeset 258a2da40ef0 (bug 1469566) for failing dom/push/test/test_subscription_change.html
authorCoroiu Cristina <ccoroiu@mozilla.com>
Tue, 19 Jun 2018 22:06:48 +0300
changeset 423066 c9bad496f81b6a56078d01836bca5a902a68aeb5
parent 423065 518b4f3f6b992d24b5433b19c012d01a524b43b4
child 423067 778e2a00786e5602f331349987622ab999271b22
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)
bugs1469566
milestone62.0a1
backs out258a2da40ef0bdbd538eddb4680fc1b511875b88
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
Backed out changeset 258a2da40ef0 (bug 1469566) for failing dom/push/test/test_subscription_change.html
dom/serviceworkers/ServiceWorkerPrivate.cpp
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -250,27 +250,29 @@ enum ExtendableEventResult {
 class ExtendableEventCallback {
 public:
   virtual void
   FinishedWithResult(ExtendableEventResult aResult) = 0;
 
   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
 };
 
-class KeepAliveHandler final : public ExtendableEvent::ExtensionsHandler
+class KeepAliveHandler final : public WorkerHolder
+                             , 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;
@@ -284,42 +286,36 @@ class KeepAliveHandler final : public Ex
   // any of them were rejected.
   bool mRejected;
 
 public:
   NS_DECL_ISUPPORTS
 
   explicit KeepAliveHandler(const nsMainThreadPtrHandle<KeepAliveToken>& aKeepAliveToken,
                             ExtendableEventCallback* aCallback)
-    : mKeepAliveToken(aKeepAliveToken)
+    : WorkerHolder("KeepAliveHolder")
+    , mKeepAliveToken(aKeepAliveToken)
+    , mWorkerPrivate(GetCurrentThreadWorkerPrivate())
+    , mWorkerHolderAdded(false)
     , mCallback(aCallback)
     , mPendingPromisesCount(0)
     , mRejected(false)
   {
     MOZ_ASSERT(mKeepAliveToken);
+    MOZ_ASSERT(mWorkerPrivate);
   }
 
   bool
-  Init()
+  UseWorkerHolder()
   {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
-    RefPtr<KeepAliveHandler> self = this;
-    mWorkerRef =
-      StrongWorkerRef::Create(GetCurrentThreadWorkerPrivate(),
-                              "KeepAliveHandler",
-                              [self]() {
-        self->MaybeCleanup();
-      });
-
-    if (NS_WARN_IF(!mWorkerRef)) {
-      return false;
-    }
-
-    return true;
+    MOZ_ASSERT(mWorkerPrivate);
+    mWorkerPrivate->AssertIsOnWorkerThread();
+    MOZ_ASSERT(!mWorkerHolderAdded);
+    mWorkerHolderAdded = HoldWorker(mWorkerPrivate, Terminating);
+    return mWorkerHolderAdded;
   }
 
   bool
   WaitOnPromise(Promise& aPromise) override
   {
     if (!mKeepAliveToken) {
       MOZ_ASSERT(!mSelfRef, "We shouldn't be holding a self reference!");
       return false;
@@ -342,20 +338,34 @@ 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(IsCurrentThreadRunningWorker());
+    MOZ_ASSERT(mWorkerPrivate);
+    mWorkerPrivate->AssertIsOnWorkerThread();
 
     if (mPendingPromisesCount || !mKeepAliveToken) {
       return;
     }
     if (mCallback) {
       mCallback->FinishedWithResult(mRejected ? Rejected : Resolved);
     }
 
@@ -366,23 +376,25 @@ private:
   ~KeepAliveHandler()
   {
     MaybeCleanup();
   }
 
   void
   MaybeCleanup()
   {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
+    MOZ_ASSERT(mWorkerPrivate);
+    mWorkerPrivate->AssertIsOnWorkerThread();
     if (!mKeepAliveToken) {
       return;
     }
+    if (mWorkerHolderAdded) {
+      ReleaseWorker();
+    }
 
-    mWorkerRef = nullptr;
     mKeepAliveToken = nullptr;
     mSelfRef = nullptr;
   }
 
   class MaybeDoneRunner : public MicroTaskRunnable
   {
   public:
     explicit MaybeDoneRunner(KeepAliveHandler* aHandler) : mHandler(aHandler) {}
@@ -392,17 +404,18 @@ private:
     }
 
     RefPtr<KeepAliveHandler> mHandler;
   };
 
   void
   RemovePromise(ExtendableEventResult aResult)
   {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
+    MOZ_ASSERT(mWorkerPrivate);
+    mWorkerPrivate->AssertIsOnWorkerThread();
     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.
 
@@ -478,17 +491,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->Init())) {
+    if (NS_WARN_IF(!keepAliveHandler->UseWorkerHolder())) {
       return NS_ERROR_FAILURE;
     }
 
     // This must always be set *before* dispatching the event, otherwise
     // waitUntil calls will fail.
     aEvent->SetKeepAliveHandler(keepAliveHandler);
 
     ErrorResult result;