Bug 1463494 - Delete the sensor observerlist array in a deferred manner. r=froydnj, r=jchen, a=abillings
authorRandell Jesup <rjesup@jesup.org>
Fri, 25 May 2018 21:16:28 -0400
changeset 802260 a5ab68f0fdf09446f9af2c87854018edea00b916
parent 802259 633bd6d37172b383fc47c086aaf6df6d951c9dd5
child 802261 094590abbf52caa2634bdf09c882b05fc87b5f5c
push id111850
push userbmo:tom@mozilla.com
push dateThu, 31 May 2018 16:41:37 +0000
reviewersfroydnj, jchen, abillings
bugs1463494
milestone60.0.2
Bug 1463494 - Delete the sensor observerlist array in a deferred manner. r=froydnj, r=jchen, a=abillings Clean up sensorlist if Dispatch fails.
hal/Hal.cpp
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -521,24 +521,39 @@ UnregisterSensorObserver(SensorType aSen
   }
 
   SensorObserverList &observers = GetSensorObservers(aSensor);
   if (!observers.RemoveObserver(aObserver) || observers.Length() > 0) {
     return;
   }
   DisableSensorNotifications(aSensor);
 
-  // Destroy sSensorObservers only if all observer lists are empty.
   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     if (gSensorObservers[i].Length() > 0) {
       return;
     }
   }
-  delete [] gSensorObservers;
+
+  // We want to destroy gSensorObservers if all observer lists are
+  // empty, but we have to defer the deallocation via a runnable to
+  // mainthread (since we may be inside NotifySensorChange()/Broadcast()
+  // when it calls UnregisterSensorObserver()).
+  SensorObserverList* sensorlists = gSensorObservers;
   gSensorObservers = nullptr;
+
+  // Unlike DispatchToMainThread, DispatchToCurrentThread doesn't leak a runnable if
+  // it fails (and we assert we're on MainThread).
+  if (NS_FAILED(NS_DispatchToCurrentThread(NS_NewRunnableFunction("UnregisterSensorObserver",
+                                                                  [sensorlists]() -> void {
+      delete [] sensorlists;
+      }))))
+  {
+    // Still need to delete sensorlists if the dispatch fails
+    delete [] sensorlists;
+  }
 }
 
 void
 NotifySensorChange(const SensorData &aSensorData) {
   SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
 
   AssertMainThread();