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 290181 9d73e42396c8b5d1a59fc6ebd1537e6e8599fdf3
parent 290180 403d085af5dd6ac5a77ee095452fb7a6ff71cc7f
child 290182 4029d2aeb270615d941f0a441bc2555978e1fa11
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1256061, 1238427
milestone48.0a1
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
 ////////////////////////////////////////////////////