Bug 1256061 - Hold a strong reference to a request when we call a method on it. r=jdm, a=ritu
authorAndrew McCreight <continuation@gmail.com>
Wed, 23 Mar 2016 12:59:14 -0700
changeset 310287 12c404b3d3e14842ac4ff0a604a9a37df6f013c7
parent 310286 b5043e21ada3bf983b1052b3daf3f5ee47fd9b62
child 310288 6ff2fe5a07d99d40cbf32485125efd484119514b
push id9318
push userryanvm@gmail.com
push dateFri, 25 Mar 2016 21:42:02 +0000
treeherdermozilla-aurora@5629a22932f7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm, ritu
bugs1256061, 1238427
milestone47.0a2
Bug 1256061 - Hold a strong reference to a request when we call a method on it. r=jdm, a=ritu I think it is possible for the TimerCallbackHolder to fire off a Notify() while the geolocation object and the nsGeolocationRequest are only holding each other alive, so they would be freed by the cycle collector the next time it runs, but we haven't run the cycle collector yet. If that happens, then Geolocation::RemoveRequest() would break the cycle, causing stuff to unravel and bad things to happen. To fix this, we just hold the request alive in TimerCallbackHolder::Notify(), which will also ensure that the geolocation object is alive, hopefully preventing crashes. This will make the Notify() behavior similar to what it was before bug 1238427, when the nsITimer object would hold a strong reference to the request when the Notify() was being run.
dom/geolocation/nsGeolocation.cpp
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -771,17 +771,18 @@ nsGeolocationRequest::Shutdown()
 ////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS(nsGeolocationRequest::TimerCallbackHolder, nsISupports, nsITimerCallback)
 
 NS_IMETHODIMP
 nsGeolocationRequest::TimerCallbackHolder::Notify(nsITimer*)
 {
   if (mRequest) {
-    mRequest->Notify();
+    RefPtr<nsGeolocationRequest> request(mRequest);
+    request->Notify();
   }
   return NS_OK;
 }
 
 
 ////////////////////////////////////////////////////
 // nsGeolocationService
 ////////////////////////////////////////////////////