Bug 940779 - Restrict the scope of a MessageEventInit so it cannot be live across a GC call, r=bent
authorSteve Fink <sfink@mozilla.com>
Tue, 19 Nov 2013 23:03:32 -0800
changeset 156634 4088133a80e698e2a15502b4978ffd6f1a3b0a01
parent 156633 335ec0f81eadfa80aaead3268dfb9d83657a8a88
child 156635 972924aa711072a0bd6ee233fd242d3245d2a110
push id25684
push usercbook@mozilla.com
push dateThu, 21 Nov 2013 13:21:05 +0000
treeherdermozilla-central@7427eede548f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs940779
milestone28.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
Bug 940779 - Restrict the scope of a MessageEventInit so it cannot be live across a GC call, r=bent
dom/workers/WorkerPrivate.cpp
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -5254,26 +5254,33 @@ WorkerPrivate::ConnectMessagePort(JSCont
     return false;
   }
 
   GlobalObject globalObject(aCx, jsGlobal);
   if (globalObject.Failed()) {
     return false;
   }
 
-  MessageEventInit init;
-  init.mBubbles = false;
-  init.mCancelable = false;
-  init.mSource = &jsPort.toObject();
-
-  ErrorResult rv;
-
-  nsRefPtr<nsDOMMessageEvent> event =
-    nsDOMMessageEvent::Constructor(globalObject, aCx,
-                                   NS_LITERAL_STRING("connect"), init, rv);
+  nsRefPtr<nsDOMMessageEvent> event;
+  {
+    // Bug 940779 - MessageEventInit contains unrooted JS objects, and
+    // ~nsRefPtr can GC, so make sure 'init' is no longer live before ~nsRefPtr
+    // runs (or the nsRefPtr is even created) to avoid a rooting hazard. Note
+    // that 'init' is live until its destructor runs, not just until its final
+    // use.
+    MessageEventInit init;
+    init.mBubbles = false;
+    init.mCancelable = false;
+    init.mSource = &jsPort.toObject();
+
+    ErrorResult rv;
+    event = nsDOMMessageEvent::Constructor(globalObject, aCx,
+                                           NS_LITERAL_STRING("connect"),
+                                           init, rv);
+  }
 
   event->SetTrusted(true);
 
   nsTArray<nsRefPtr<MessagePortBase>> ports;
   ports.AppendElement(port);
 
   nsRefPtr<MessagePortList> portList =
     new MessagePortList(static_cast<nsIDOMEventTarget*>(globalScope), ports);