Bug 637957 - Make results notifier hold a strong reference to mCallback, to prevent it being destroyed prematurely.
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 02 Mar 2011 19:55:08 +0100
changeset 63280 29040397114927156f83b862e4e41befcbbdd9c9
parent 63279 b6fd106a4eb3bd23b08c2dbc0f9f24f304701298
child 63281 7bc88a8f9095ec8f9c7bceb5ccb3d77779c5bf1b
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
bugs637957
milestone2.0b13pre
Bug 637957 - Make results notifier hold a strong reference to mCallback, to prevent it being destroyed prematurely. r=sdwilsh a=blocker
storage/src/mozStorageAsyncStatementExecution.cpp
--- a/storage/src/mozStorageAsyncStatementExecution.cpp
+++ b/storage/src/mozStorageAsyncStatementExecution.cpp
@@ -92,18 +92,24 @@ public:
     , mEventStatus(aEventStatus)
   {
   }
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(mCallback, "Trying to notify about results without a callback!");
 
-    if (mEventStatus->shouldNotify())
+    if (mEventStatus->shouldNotify()) {
+      // 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 = mCallback;
+
       (void)mCallback->HandleResult(mResults);
+    }
 
     return NS_OK;
   }
 
 private:
   mozIStorageStatementCallback *mCallback;
   nsCOMPtr<mozIStorageResultSet> mResults;
   nsRefPtr<AsyncExecuteStatements> mEventStatus;
@@ -121,18 +127,24 @@ public:
       mCallback(aCallback)
     , mErrorObj(aErrorObj)
     , mEventStatus(aEventStatus)
   {
   }
 
   NS_IMETHOD Run()
   {
-    if (mEventStatus->shouldNotify() && mCallback)
+    if (mEventStatus->shouldNotify() && 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 = mCallback;
+
       (void)mCallback->HandleError(mErrorObj);
+    }
 
     return NS_OK;
   }
 
 private:
   mozIStorageStatementCallback *mCallback;
   nsCOMPtr<mozIStorageError> mErrorObj;
   nsRefPtr<AsyncExecuteStatements> mEventStatus;