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 idunknown
push userunknown
push dateunknown
bugs637957
milestone2.0b13pre
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 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;