Bug 785248: Clear the worker's queue when terminating, even if we never ran any script. r=bent
authorKyle Huey <khuey@kylehuey.com>
Tue, 02 Oct 2012 19:03:28 -0700
changeset 109094 6e04928c99aace512db1d28fa5ffb10a08cb527c
parent 109093 1797401e19ce70a303983563e66f6501acb4c1eb
child 109095 4d5e812682389945e07e5a4bc40a1d695cba6d61
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersbent
bugs785248
milestone18.0a1
Bug 785248: Clear the worker's queue when terminating, even if we never ran any script. r=bent
dom/workers/WorkerPrivate.cpp
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3477,46 +3477,52 @@ WorkerPrivate::NotifyInternal(JSContext*
   NS_ASSERTION(previousStatus != Pending, "How is this possible?!");
 
   NS_ASSERTION(previousStatus >= Canceling || mKillTime.IsNull(),
                "Bad kill time set!");
 
   // Let all our features know the new status.
   NotifyFeatures(aCx, aStatus);
 
-  // There's nothing to do here if we never succeeded in running the worker
-  // script or if the close handler has already run.
-  if (!JS_GetGlobalObject(aCx) || mCloseHandlerFinished) {
+  // If this is the first time our status has changed then we need to clear the
+  // main event queue.
+  if (previousStatus == Running) {
+    MutexAutoLock lock(mMutex);
+    ClearQueue(&mQueue);
+  }
+
+  // If we've run the close handler, we don't need to do anything else.
+  if (mCloseHandlerFinished) {
     return true;
   }
 
-  // If this is the first time our status has changed then we need to clear the
-  // main event queue. We also need to schedule the close handler unless we're
-  // being shut down.
-  if (previousStatus == Running) {
+  // If the worker script never ran, or failed to compile, we don't need to do
+  // anything else, except pretend that we ran the close handler.
+  if (!JS_GetGlobalObject(aCx)) {
+    mCloseHandlerStarted = true;
+    mCloseHandlerFinished = true;
+    return true;
+  }
+
+  // If this is the first time our status has changed we also need to schedule
+  // the close handler unless we're being shut down.
+  if (previousStatus == Running && aStatus != Killing) {
     NS_ASSERTION(!mCloseHandlerStarted && !mCloseHandlerFinished,
                  "This is impossible!");
 
-    {
-      MutexAutoLock lock(mMutex);
-      ClearQueue(&mQueue);
+    nsRefPtr<CloseEventRunnable> closeRunnable = new CloseEventRunnable(this);
+
+    MutexAutoLock lock(mMutex);
+
+    if (!mQueue.Push(closeRunnable)) {
+      NS_WARNING("Failed to push closeRunnable!");
+      return false;
     }
 
-    if (aStatus != Killing) {
-      nsRefPtr<CloseEventRunnable> closeRunnable = new CloseEventRunnable(this);
-
-      MutexAutoLock lock(mMutex);
-
-      if (!mQueue.Push(closeRunnable)) {
-        NS_WARNING("Failed to push closeRunnable!");
-        return false;
-      }
-
-      closeRunnable.forget();
-    }
+    closeRunnable.forget();
   }
 
   if (aStatus == Closing) {
     // Notify parent to stop sending us messages and balance our busy count.
     nsRefPtr<CloseRunnable> runnable = new CloseRunnable(this);
     if (!runnable->Dispatch(aCx)) {
       return false;
     }