Bug 1319334 - Resolve ready promise *after* updating registration.state properties. r=bkelly
--- 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>