Bug 637957 - Make notifiers strong owners of mCallback, to prevent crashes due to unexpected events ordering
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 09 Mar 2011 13:31:44 -0800
changeset 27352 e32983ecfaf97ce6d7966c376dfa3c31afcc7e33
parent 27351 facd39641206b6851f9065ee8877e3d674ff3496
child 27353 1c11b640be1aabdd0006f67d56f583318d568ea0
push id2687
push usersdwilsh@shawnwilsher.com
push dateWed, 09 Mar 2011 21:33:33 +0000
bugs637957
milestone1.9.1.18pre
Bug 637957 - Make notifiers strong owners of mCallback, to prevent crashes due to unexpected events ordering r=sdwilsh a=drivers
storage/src/mozStorageEvents.cpp
--- a/storage/src/mozStorageEvents.cpp
+++ b/storage/src/mozStorageEvents.cpp
@@ -106,18 +106,25 @@ public:
     , mEventStatus(aEventStatus)
   {
   }
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(mCallback, "Trying to notify about results without a callback!");
 
-    if (mEventStatus->runEvent())
+    if (mEventStatus->runEvent()) {
+      // Hold a strong reference to the callback while notifying it, so that if
+      // it spins the event loop, the callback won't be released and freed out
+      // from under us.
+      nsCOMPtr<mozIStorageStatementCallback> callback =
+        do_QueryInterface(mCallback);
+
       (void)mCallback->HandleResult(mResults);
+    }
 
     return NS_OK;
   }
 
 private:
   CallbackResultNotifier() { }
 
   mozIStorageStatementCallback *mCallback;
@@ -143,18 +150,25 @@ public:
       mCallback(aCallback)
     , mErrorObj(aErrorObj)
     , mEventStatus(aEventStatus)
   {
   }
 
   NS_IMETHOD Run()
   {
-    if (mEventStatus->runEvent() && mCallback)
+    if (mEventStatus->runEvent() && mCallback) {
+      // Hold a strong reference to the callback while notifying it, so that if
+      // it spins the event loop, the callback won't be released and freed out
+      // from under us.
+      nsCOMPtr<mozIStorageStatementCallback> callback =
+        do_QueryInterface(mCallback);
+
       (void)mCallback->HandleError(mErrorObj);
+    }
 
     return NS_OK;
   }
 
 private:
   ErrorNotifier() { }
 
   mozIStorageStatementCallback *mCallback;