Bug 1319334 - Resolve ready promise *after* updating registration.state properties. r=bkelly
authorCatalin Badea <catalin.badea392@gmail.com>
Tue, 22 Nov 2016 06:38:00 +0800
changeset 323897 1dcdef45d753e0fa011389e8713a50a7051d4342
parent 323896 2bbc7be933e2cd52fb1e328119075cf9aab50c5f
child 323898 dd83ff2a1d8595908a4da05b432d9cd08a7f59ec
push id30985
push usercbook@mozilla.com
push dateWed, 23 Nov 2016 15:39:29 +0000
treeherdermozilla-central@47f42f21541b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1319334
milestone53.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 1319334 - Resolve ready promise *after* updating registration.state properties. r=bkelly
dom/workers/ServiceWorkerRegistrationInfo.cpp
dom/workers/test/serviceworkers/test_worker_reference_gc_timeout.html
--- a/dom/workers/ServiceWorkerRegistrationInfo.cpp
+++ b/dom/workers/ServiceWorkerRegistrationInfo.cpp
@@ -235,20 +235,18 @@ ServiceWorkerRegistrationInfo::Activate(
   if (!mWaitingWorker) {
     return;
   }
 
   TransitionWaitingToActive();
 
   // FIXME(nsm): Unlink appcache if there is one.
 
+  // "Queue a task to fire a simple event named controllerchange..."
   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-  swm->CheckPendingReadyPromises();
-
-  // "Queue a task to fire a simple event named controllerchange..."
   nsCOMPtr<nsIRunnable> controllerChangeRunnable =
     NewRunnableMethod<RefPtr<ServiceWorkerRegistrationInfo>>(
       swm, &ServiceWorkerManager::FireControllerChange, this);
   NS_DispatchToMainThread(controllerChangeRunnable);
 
   nsCOMPtr<nsIRunnable> failRunnable =
     NewRunnableMethod<bool>(this,
                             &ServiceWorkerRegistrationInfo::FinishActivate,
@@ -314,16 +312,20 @@ ServiceWorkerRegistrationInfo::AsyncUpda
 {
   AssertIsOnMainThread();
   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   if (aTransition == Invalidate) {
     swm->InvalidateServiceWorkerRegistrationWorker(this, aWorker);
   } else {
     MOZ_ASSERT(aTransition == TransitionToNextState);
     swm->TransitionServiceWorkerRegistrationWorker(this, aWorker);
+
+    if (aWorker == WhichServiceWorker::WAITING_WORKER) {
+      swm->CheckPendingReadyPromises();
+    }
   }
 }
 
 void
 ServiceWorkerRegistrationInfo::UpdateRegistrationStateProperties(WhichServiceWorker aWorker,
                                                                  TransitionType aTransition)
 {
   AssertIsOnMainThread();
--- a/dom/workers/test/serviceworkers/test_worker_reference_gc_timeout.html
+++ b/dom/workers/test/serviceworkers/test_worker_reference_gc_timeout.html
@@ -23,34 +23,55 @@ SimpleTest.requestFlakyTimeout("Forcing 
 
 add_task(function setupPrefs() {
   return SpecialPowers.pushPrefEnv({"set": [
     ["dom.serviceWorkers.enabled", true],
     ["dom.serviceWorkers.testing.enabled", true],
   ]});
 });
 
-//var worker;
 add_task(function* test_worker_ref_gc() {
   let registration = yield navigator.serviceWorker.register(
     "lazy_worker.js", { scope: "./lazy_worker_scope_timeout"} )
     .then(function(registration) {
       SpecialPowers.exactGC();
       var worker = registration.installing;
       return new Promise(function(resolve) {
         worker.addEventListener('statechange', function() {
           info("state is " + worker.state + "\n");
           SpecialPowers.exactGC();
           if (worker.state === 'activated') {
             resolve(registration);
           }
         });
       });
     });
-
   ok(true, "Got activated event!");
 
   yield registration.unregister();
+});
+
+add_task(function* test_worker_ref_gc_ready_promise() {
+  let wait_active = navigator.serviceWorker.ready.then(function(reg) {
+    SpecialPowers.exactGC();
+    ok(reg.active, "Got active worker.");
+    ok(reg.active.state === "activating", "Worker is in activating state");
+    return new Promise(function(res) {
+      reg.active.onstatechange = function(e) {
+        reg.active.onstatechange = null;
+        ok(reg.active.state === "activated", "Worker was activated");
+        res();
+      }
+    });
+  });
+
+  let registration = yield navigator.serviceWorker.register(
+    "lazy_worker.js", { scope: "."} );
+  yield wait_active;
+  yield registration.unregister();
+});
+
+add_task(function* cleanup() {
   yield SpecialPowers.popPrefEnv();
 });
 </script>
 </body>
 </html>