From d002e5fc4b9703ebc981d173d898a1404a2e26d5 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Fri, 23 Jan 2015 19:49:39 -0800 Subject: [PATCH] Backed out changeset 3ff80c877212 (bug 1113627) for asan mochitest-4 bustage on a CLOSED TREE --- dom/webidl/InstallEvent.webidl | 2 +- dom/workers/ServiceWorkerManager.cpp | 341 ++++++++++++++++----------- dom/workers/ServiceWorkerManager.h | 7 - 3 files changed, 210 insertions(+), 140 deletions(-) diff --git a/dom/webidl/InstallEvent.webidl b/dom/webidl/InstallEvent.webidl index aeb436077ebb..7b770191bef4 100644 --- a/dom/webidl/InstallEvent.webidl +++ b/dom/webidl/InstallEvent.webidl @@ -16,6 +16,6 @@ interface InstallEvent : ExtendableEvent { // Should be in the spec soon to satisfy conventions about events. // https://github.com/slightlyoff/ServiceWorker/issues/216. -dictionary InstallEventInit : ExtendableEventInit { +dictionary InstallEventInit : EventInit { ServiceWorker? activeWorker = null; }; diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index 3d135eb66252..20c411ce6a1d 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -106,6 +106,26 @@ ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo() } } +class QueueFireUpdateFoundRunnable MOZ_FINAL : public nsRunnable +{ + nsRefPtr mRegistration; +public: + explicit QueueFireUpdateFoundRunnable(ServiceWorkerRegistrationInfo* aReg) + : mRegistration(aReg) + { + MOZ_ASSERT(aReg); + } + + NS_IMETHOD + Run() + { + nsRefPtr swm = ServiceWorkerManager::GetInstance(); + swm->FireEventOnServiceWorkerRegistrations(mRegistration, + NS_LITERAL_STRING("updatefound")); + return NS_OK; + } +}; + ////////////////////////// // ServiceWorkerManager // ////////////////////////// @@ -143,60 +163,17 @@ ServiceWorkerManager::CleanupServiceWorkerInformation(const nsACString& aDomain, class ServiceWorkerRegisterJob; -class ContinueLifecycleTask : public nsISupports +class FinishInstallRunnable MOZ_FINAL : public nsRunnable { - NS_DECL_ISUPPORTS - -protected: - virtual ~ContinueLifecycleTask() - { } - -public: - virtual void ContinueAfterWorkerEvent(bool aSuccess, - bool aActivateImmediately) = 0; -}; - -NS_IMPL_ISUPPORTS0(ContinueLifecycleTask); - -class ContinueInstallTask MOZ_FINAL : public ContinueLifecycleTask -{ - nsRefPtr mJob; - -public: - explicit ContinueInstallTask(ServiceWorkerRegisterJob* aJob) - : mJob(aJob) - { } - - void ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately) MOZ_OVERRIDE; -}; - -class ContinueActivateTask MOZ_FINAL : public ContinueLifecycleTask -{ - nsRefPtr mRegistration; - -public: - explicit ContinueActivateTask(ServiceWorkerRegistrationInfo* aReg) - : mRegistration(aReg) - { } - - void - ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately /* unused */) MOZ_OVERRIDE - { - mRegistration->FinishActivate(aSuccess); - } -}; - -class ContinueLifecycleRunnable MOZ_FINAL : public nsRunnable -{ - nsMainThreadPtrHandle mTask; + nsMainThreadPtrHandle mJob; bool mSuccess; bool mActivateImmediately; public: - ContinueLifecycleRunnable(const nsMainThreadPtrHandle& aTask, - bool aSuccess, - bool aActivateImmediately) - : mTask(aTask) + explicit FinishInstallRunnable(const nsMainThreadPtrHandle& aJob, + bool aSuccess, + bool aActivateImmediately) + : mJob(aJob) , mSuccess(aSuccess) , mActivateImmediately(aActivateImmediately) { @@ -204,12 +181,7 @@ public: } NS_IMETHOD - Run() MOZ_OVERRIDE - { - AssertIsOnMainThread(); - mTask->ContinueAfterWorkerEvent(mSuccess, mActivateImmediately); - return NS_OK; - } + Run() MOZ_OVERRIDE; }; /* @@ -218,33 +190,33 @@ public: * ServiceWorkers, so the parent thread -> worker thread requirement for * runnables is satisfied. */ -class LifecycleEventWorkerRunnable MOZ_FINAL : public WorkerRunnable +class InstallEventRunnable MOZ_FINAL : public WorkerRunnable { - nsString mEventName; - nsMainThreadPtrHandle mTask; + nsMainThreadPtrHandle mJob; + nsCString mScope; public: - LifecycleEventWorkerRunnable(WorkerPrivate* aWorkerPrivate, - const nsString& aEventName, - const nsMainThreadPtrHandle& aTask) - : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount) - , mEventName(aEventName) - , mTask(aTask) + InstallEventRunnable(WorkerPrivate* aWorkerPrivate, + const nsMainThreadPtrHandle& aJob, + const nsCString& aScope) + : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount), + mJob(aJob), + mScope(aScope) { AssertIsOnMainThread(); MOZ_ASSERT(aWorkerPrivate); } bool - WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { MOZ_ASSERT(aWorkerPrivate); - return DispatchLifecycleEvent(aCx, aWorkerPrivate); + return DispatchInstallEvent(aCx, aWorkerPrivate); } private: bool - DispatchLifecycleEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate); + DispatchInstallEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate); }; @@ -384,7 +356,7 @@ public: class ServiceWorkerRegisterJob MOZ_FINAL : public ServiceWorkerJob, public nsIStreamLoaderObserver { - friend class ContinueInstallTask; + friend class FinishInstallRunnable; nsCString mScope; nsCString mScriptSpec; @@ -558,14 +530,15 @@ public: Succeed(); - nsCOMPtr upr = - NS_NewRunnableMethodWithArg(swm, - &ServiceWorkerManager::FireUpdateFound, - mRegistration); + nsRefPtr upr = + new QueueFireUpdateFoundRunnable(mRegistration); NS_DispatchToMainThread(upr); - nsMainThreadPtrHandle handle( - new nsMainThreadPtrHolder(new ContinueInstallTask(this))); + // XXXnsm this leads to double fetches right now, ideally we'll be able to + // use the persistent cache later. + nsRefPtr upcasted = this; + nsMainThreadPtrHandle handle( + new nsMainThreadPtrHolder(upcasted)); nsRefPtr serviceWorker; nsresult rv = @@ -578,8 +551,8 @@ public: return; } - nsRefPtr r = - new LifecycleEventWorkerRunnable(serviceWorker->GetWorkerPrivate(), NS_LITERAL_STRING("install"), handle); + nsRefPtr r = + new InstallEventRunnable(serviceWorker->GetWorkerPrivate(), handle, mRegistration->mScope); AutoJSAPI jsapi; jsapi.Init(); @@ -755,12 +728,6 @@ ContinueUpdateRunnable::Run() return NS_OK; } -void -ContinueInstallTask::ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmediately) -{ - mJob->ContinueAfterInstallEvent(aSuccess, aActivateImmediately); -} - // If we return an error code here, the ServiceWorkerContainer will // automatically reject the Promise. NS_IMETHODIMP @@ -909,23 +876,33 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow, return NS_OK; } -/* - * Used to handle ExtendableEvent::waitUntil() and proceed with - * installation/activation. - */ -class LifecycleEventPromiseHandler MOZ_FINAL : public PromiseNativeHandler +NS_IMETHODIMP +FinishInstallRunnable::Run() { - nsMainThreadPtrHandle mTask; + AssertIsOnMainThread(); + nsRefPtr job = static_cast(mJob.get()); + nsRefPtr upjob = static_cast(job.get()); + MOZ_ASSERT(upjob); + upjob->ContinueAfterInstallEvent(mSuccess, mActivateImmediately); + return NS_OK; +} + +/* + * Used to handle InstallEvent::waitUntil() and proceed with installation. + */ +class FinishInstallHandler MOZ_FINAL : public PromiseNativeHandler +{ + nsMainThreadPtrHandle mJob; bool mActivateImmediately; virtual - ~LifecycleEventPromiseHandler() + ~FinishInstallHandler() { } public: - LifecycleEventPromiseHandler(const nsMainThreadPtrHandle& aTask, - bool aActivateImmediately) - : mTask(aTask) + FinishInstallHandler(const nsMainThreadPtrHandle& aJob, + bool aActivateImmediately) + : mJob(aJob) , mActivateImmediately(aActivateImmediately) { MOZ_ASSERT(!NS_IsMainThread()); @@ -938,47 +915,33 @@ public: MOZ_ASSERT(workerPrivate); workerPrivate->AssertIsOnWorkerThread(); - nsRefPtr r = - new ContinueLifecycleRunnable(mTask, true /* success */, mActivateImmediately); + nsRefPtr r = new FinishInstallRunnable(mJob, true, mActivateImmediately); NS_DispatchToMainThread(r); } void RejectedCallback(JSContext* aCx, JS::Handle aValue) MOZ_OVERRIDE { - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - MOZ_ASSERT(workerPrivate); - workerPrivate->AssertIsOnWorkerThread(); - - nsRefPtr r = - new ContinueLifecycleRunnable(mTask, false /* success */, mActivateImmediately); + nsRefPtr r = new FinishInstallRunnable(mJob, false, mActivateImmediately); NS_DispatchToMainThread(r); } }; bool -LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate) +InstallEventRunnable::DispatchInstallEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { aWorkerPrivate->AssertIsOnWorkerThread(); MOZ_ASSERT(aWorkerPrivate->IsServiceWorker()); + InstallEventInit init; + init.mBubbles = false; + init.mCancelable = true; - nsRefPtr event; + // FIXME(nsm): Bug 982787 pass previous active worker. + + // FIXME(nsm): Set error handler so we can grab handler errors. nsRefPtr target = aWorkerPrivate->GlobalScope(); - - if (mEventName.EqualsASCII("install")) { - // FIXME(nsm): Bug 982787 pass previous active worker. - InstallEventInit init; - init.mBubbles = false; - init.mCancelable = true; - event = InstallEvent::Constructor(target, mEventName, init); - } else if (mEventName.EqualsASCII("activate")) { - ExtendableEventInit init; - init.mBubbles = false; - init.mCancelable = true; - event = ExtendableEvent::Constructor(target, mEventName, init); - } else { - MOZ_CRASH("Unexpected lifecycle event"); - } + nsRefPtr event = + InstallEvent::Constructor(target, NS_LITERAL_STRING("install"), init); event->SetTrusted(true); @@ -1012,21 +975,135 @@ LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx, WorkerPriva return false; } - // activateimmediately is only relevant to "install" event. - bool activateImmediately = false; - InstallEvent* downCast = static_cast(event.get()); - if (downCast) { - activateImmediately = downCast->ActivateImmediately(); - // FIXME(nsm): Set activeWorker to the correct thing. - // FIXME(nsm): Install error handler for any listener errors. - } - - nsRefPtr handler = - new LifecycleEventPromiseHandler(mTask, activateImmediately); + nsRefPtr handler = + new FinishInstallHandler(mJob, event->ActivateImmediately()); waitUntilPromise->AppendNativeHandler(handler); return true; } +class FinishActivationRunnable MOZ_FINAL : public nsRunnable +{ + bool mSuccess; + nsMainThreadPtrHandle mRegistration; + +public: + FinishActivationRunnable(bool aSuccess, + const nsMainThreadPtrHandle& aRegistration) + : mSuccess(aSuccess) + , mRegistration(aRegistration) + { + MOZ_ASSERT(!NS_IsMainThread()); + } + + NS_IMETHODIMP + Run() + { + AssertIsOnMainThread(); + + mRegistration->FinishActivate(mSuccess); + return NS_OK; + } +}; + +class FinishActivateHandler MOZ_FINAL : public PromiseNativeHandler +{ + nsMainThreadPtrHandle mRegistration; + +public: + explicit FinishActivateHandler(const nsMainThreadPtrHandle& aRegistration) + : mRegistration(aRegistration) + { + MOZ_ASSERT(!NS_IsMainThread()); + } + + virtual + ~FinishActivateHandler() + { } + + void + ResolvedCallback(JSContext* aCx, JS::Handle aValue) MOZ_OVERRIDE + { + nsRefPtr r = new FinishActivationRunnable(true /* success */, mRegistration); + NS_DispatchToMainThread(r); + } + + void + RejectedCallback(JSContext* aCx, JS::Handle aValue) MOZ_OVERRIDE + { + nsRefPtr r = new FinishActivationRunnable(false /* success */, mRegistration); + NS_DispatchToMainThread(r); + } +}; + +class ActivateEventRunnable : public WorkerRunnable +{ + nsMainThreadPtrHandle mRegistration; + +public: + ActivateEventRunnable(WorkerPrivate* aWorkerPrivate, + const nsMainThreadPtrHandle& aRegistration) + : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount), + mRegistration(aRegistration) + { + MOZ_ASSERT(aWorkerPrivate); + } + + bool + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + { + MOZ_ASSERT(aWorkerPrivate); + return DispatchActivateEvent(aCx, aWorkerPrivate); + } + +private: + bool + DispatchActivateEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + { + MOZ_ASSERT(aWorkerPrivate->IsServiceWorker()); + nsRefPtr target = do_QueryObject(aWorkerPrivate->GlobalScope()); + + // FIXME(nsm): Set activeWorker to the correct thing. + EventInit init; + init.mBubbles = false; + init.mCancelable = true; + nsRefPtr event = + ExtendableEvent::Constructor(target, NS_LITERAL_STRING("activate"), init); + + event->SetTrusted(true); + + nsRefPtr waitUntilPromise; + + // FIXME(nsm): Install error handler for any listener errors. + ErrorResult result; + result = target->DispatchDOMEvent(nullptr, event, nullptr, nullptr); + WidgetEvent* internalEvent = event->GetInternalNSEvent(); + if (!result.Failed() && !internalEvent->mFlags.mExceptionHasBeenRisen) { + waitUntilPromise = event->GetPromise(); + if (!waitUntilPromise) { + nsCOMPtr global = + do_QueryObject(aWorkerPrivate->GlobalScope()); + waitUntilPromise = + Promise::Resolve(global, + aCx, JS::UndefinedHandleValue, result); + } + } else { + nsCOMPtr global = + do_QueryObject(aWorkerPrivate->GlobalScope()); + // Continue with a canceled install. + waitUntilPromise = Promise::Reject(global, aCx, + JS::UndefinedHandleValue, result); + } + + if (result.Failed()) { + return false; + } + + nsRefPtr handler = new FinishActivateHandler(mRegistration); + waitUntilPromise->AppendNativeHandler(handler); + return true; + } +}; + void ServiceWorkerRegistrationInfo::TryToActivate() { @@ -1084,11 +1161,11 @@ ServiceWorkerRegistrationInfo::Activate() return; } - nsMainThreadPtrHandle handle( - new nsMainThreadPtrHolder(new ContinueActivateTask(this))); + nsMainThreadPtrHandle handle( + new nsMainThreadPtrHolder(this)); - nsRefPtr r = - new LifecycleEventWorkerRunnable(serviceWorker->GetWorkerPrivate(), NS_LITERAL_STRING("activate"), handle); + nsRefPtr r = + new ActivateEventRunnable(serviceWorker->GetWorkerPrivate(), handle); AutoJSAPI jsapi; jsapi.Init(); diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index 5550d43e4478..f9e30194b98a 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -462,13 +462,6 @@ private: FireEventOnServiceWorkerRegistrations(ServiceWorkerRegistrationInfo* aRegistration, const nsAString& aName); - void - FireUpdateFound(ServiceWorkerRegistrationInfo* aRegistration) - { - FireEventOnServiceWorkerRegistrations(aRegistration, - NS_LITERAL_STRING("updatefound")); - } - void FireControllerChange(ServiceWorkerRegistrationInfo* aRegistration);