Bug 1256061 - Hold a strong reference to a request when we call a method on it. r=jdm
authorAndrew McCreight <continuation@gmail.com>
Wed, 23 Mar 2016 12:59:14 -0700
changeset 290122 9d73e42396c8b5d1a59fc6ebd1537e6e8599fdf3
parent 290121 403d085af5dd6ac5a77ee095452fb7a6ff71cc7f
child 290123 4029d2aeb270615d941f0a441bc2555978e1fa11
push id30114
push usercbook@mozilla.com
push dateThu, 24 Mar 2016 15:15:54 +0000
treeherdermozilla-central@24c5fbde4488 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1256061, 1238427
milestone48.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 1256061 - Hold a strong reference to a request when we call a method on it. r=jdm 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
 ////////////////////////////////////////////////////