author | Nikhil Marathe <nsm.nikhil@gmail.com> |
Fri, 24 Oct 2014 15:11:26 -0700 | |
changeset 229451 | c2bcea8dde26a82ff24571eb737806b3c5fc0d81 |
parent 229450 | 4c0ccf99cb71de69b2efeb1d532f1ed201500c2b |
child 229452 | f64c2ee330876b35637e08160fb16422e248a18e |
push id | 55705 |
push user | nsm.nikhil@gmail.com |
push date | Tue, 17 Feb 2015 18:58:45 +0000 |
treeherder | mozilla-inbound@1b86fdc1e49f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | baku |
bugs | 1041340 |
milestone | 38.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
|
--- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -1928,46 +1928,71 @@ ServiceWorkerManager::RemoveScope(nsTArr { aList.RemoveElement(aScope); } void ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc) { AssertIsOnMainThread(); - if (!Preferences::GetBool("dom.serviceWorkers.enabled")) { - return; - } - nsRefPtr<ServiceWorkerRegistrationInfo> registration = GetServiceWorkerRegistrationInfo(aDoc); if (registration) { MOZ_ASSERT(!mControlledDocuments.Contains(aDoc)); registration->StartControllingADocument(); // Use the already_AddRefed<> form of Put to avoid the addref-deref since // we don't need the registration pointer in this function anymore. mControlledDocuments.Put(aDoc, registration.forget()); } } +class ServiceWorkerActivateAfterUnloadingJob MOZ_FINAL : public ServiceWorkerJob +{ + nsRefPtr<ServiceWorkerRegistrationInfo> mRegistration; +public: + ServiceWorkerActivateAfterUnloadingJob(ServiceWorkerJobQueue* aQueue, + ServiceWorkerRegistrationInfo* aReg) + : ServiceWorkerJob(aQueue) + , mRegistration(aReg) + { } + + void + Start() + { + if (mRegistration->mPendingUninstall) { + mRegistration->Clear(); + nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); + swm->RemoveRegistration(mRegistration); + } else { + mRegistration->TryToActivate(); + } + + Done(NS_OK); + } +}; + void ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc) { MOZ_ASSERT(aDoc); - if (!Preferences::GetBool("dom.serviceWorkers.enabled")) { - return; - } - nsRefPtr<ServiceWorkerRegistrationInfo> registration; mControlledDocuments.Remove(aDoc, getter_AddRefs(registration)); // A document which was uncontrolled does not maintain that state itself, so // it will always call MaybeStopControlling() even if there isn't an // associated registration. So this check is required. if (registration) { registration->StopControllingADocument(); + if (!registration->IsControllingDocuments()) { + ServiceWorkerJobQueue* queue = GetOrCreateJobQueue(registration->mScope); + // The remaining tasks touch registration->mPendingUninstall, so queue + // them up in a job. + nsRefPtr<ServiceWorkerActivateAfterUnloadingJob> job = + new ServiceWorkerActivateAfterUnloadingJob(queue, registration); + queue->Append(job); + } } } NS_IMETHODIMP ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope) { nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, nullptr, nullptr);
--- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -285,22 +285,23 @@ public: * installation, querying and event dispatch of ServiceWorkers for all the * origins in the process. */ class ServiceWorkerManager MOZ_FINAL : public nsIServiceWorkerManager , public nsIIPCBackgroundChildCreateCallback { friend class ActivationRunnable; - friend class ServiceWorkerRegistrationInfo; - friend class ServiceWorkerRegisterJob; friend class GetReadyPromiseRunnable; friend class GetRegistrationsRunnable; friend class GetRegistrationRunnable; friend class QueueFireUpdateFoundRunnable; + friend class ServiceWorkerActivateAfterUnloadingJob; + friend class ServiceWorkerRegisterJob; + friend class ServiceWorkerRegistrationInfo; friend class ServiceWorkerUnregisterJob; public: NS_DECL_ISUPPORTS NS_DECL_NSISERVICEWORKERMANAGER NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK NS_DECLARE_STATIC_IID_ACCESSOR(NS_SERVICEWORKERMANAGER_IMPL_IID) @@ -344,16 +345,18 @@ public: } ServiceWorkerRegistrationInfo* CreateNewRegistration(const nsCString& aScope, nsIPrincipal* aPrincipal); void RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration) { + MOZ_ASSERT(aRegistration); + MOZ_ASSERT(!aRegistration->IsControllingDocuments()); MOZ_ASSERT(mServiceWorkerRegistrationInfos.Contains(aRegistration->mScope)); ServiceWorkerManager::RemoveScope(mOrderedScopes, aRegistration->mScope); mServiceWorkerRegistrationInfos.Remove(aRegistration->mScope); } ServiceWorkerJobQueue* GetOrCreateJobQueue(const nsCString& aScope) {
--- a/dom/workers/test/serviceworkers/test_installation_simple.html +++ b/dom/workers/test/serviceworkers/test_installation_simple.html @@ -135,18 +135,17 @@ window.onmessage = function(e) { if (e.data.type == "ready") { continueTest(); } else if (e.data.type == "finish") { window.onmessage = null; // We have to make frame navigate away, otherwise it will call // MaybeStopControlling() when this document is unloaded. At that point - // the pref has been disabled, and so MaybeStopControlling() will just - // return since it is currently gated. + // the pref has been disabled, so the ServiceWorkerManager is not available. frame.setAttribute("src", new URL("about:blank").href); resolve(); } else if (e.data.type == "check") { ok(e.data.status, e.data.msg); } } return p; }