diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 22e2608bab3..67620219915 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -55,6 +55,7 @@ #include "nsIURI.h" #include "nsIURL.h" #include "nsIXPConnect.h" +#include "nsIXPCScriptNotify.h" #include "jsfriendapi.h" #include "jsdbgapi.h" @@ -966,6 +967,13 @@ public: bool dummy; return DispatchEventToTarget(aCx, target, event, &dummy); } + + void PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult) + { + // Notify before WorkerRunnable::PostRun, since that can kill aWorkerPrivate + NotifyScriptExecutedIfNeeded(); + WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult); + } }; class NotifyRunnable : public WorkerControlRunnable @@ -1111,6 +1119,13 @@ public: mErrorNumber, innerWindowId); } + void PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult) + { + // Notify before WorkerRunnable::PostRun, since that can kill aWorkerPrivate + NotifyScriptExecutedIfNeeded(); + WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult); + } + static bool ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aFireAtScope, JSObject* aTarget, const nsString& aMessage, @@ -1816,6 +1831,18 @@ WorkerRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, } } +void +WorkerRunnable::NotifyScriptExecutedIfNeeded() const +{ + // if we're on the main thread notify about the end of our script execution. + if (mTarget == ParentThread && !mWorkerPrivate->GetParent()) { + AssertIsOnMainThread(); + if (mWorkerPrivate->GetScriptNotify()) { + mWorkerPrivate->GetScriptNotify()->ScriptExecuted(); + } + } +} + struct WorkerPrivate::TimeoutInfo { TimeoutInfo() @@ -1881,6 +1908,7 @@ WorkerPrivateParent::WorkerPrivateParent( mWindow.swap(aWindow); mScriptContext.swap(aScriptContext); + mScriptNotify = do_QueryInterface(mScriptContext); mBaseURI.swap(aBaseURI); mPrincipal.swap(aPrincipal); mDocument.swap(aDocument); @@ -2181,10 +2209,11 @@ WorkerPrivateParent::ForgetMainThreadObjects( AssertIsOnParentThread(); MOZ_ASSERT(!mMainThreadObjectsForgotten); - aDoomed.SetCapacity(6); + aDoomed.SetCapacity(7); SwapToISupportsArray(mWindow, aDoomed); SwapToISupportsArray(mScriptContext, aDoomed); + SwapToISupportsArray(mScriptNotify, aDoomed); SwapToISupportsArray(mBaseURI, aDoomed); SwapToISupportsArray(mScriptURI, aDoomed); SwapToISupportsArray(mPrincipal, aDoomed); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 9c9716e4c3e..b4c7b24d7bb 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -69,6 +69,7 @@ class nsIScriptContext; class nsIURI; class nsPIDOMWindow; class nsITimer; +class nsIXPCScriptNotify; BEGIN_WORKERS_NAMESPACE @@ -133,6 +134,8 @@ protected: virtual void PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult); + void NotifyScriptExecutedIfNeeded() const; + private: NS_DECL_NSIRUNNABLE }; @@ -207,6 +210,7 @@ private: // Main-thread things. nsCOMPtr mWindow; nsCOMPtr mScriptContext; + nsCOMPtr mScriptNotify; nsCOMPtr mBaseURI; nsCOMPtr mScriptURI; nsCOMPtr mPrincipal; @@ -386,6 +390,13 @@ public: return mScriptContext; } + nsIXPCScriptNotify* + GetScriptNotify() const + { + AssertIsOnMainThread(); + return mScriptNotify; + } + JSObject* GetJSObject() const {