Bug 1169994 Fix Cache to close connection on right thread when init is canceled. r=ehsan
authorBen Kelly <ben@wanderview.com>
Wed, 10 Jun 2015 06:37:16 -0700
changeset 248057 168cdb48c5ebb33f8067918e67081c92234c7631
parent 248056 dfdca3f63b4872dc87765b89707c9b8ce1f87264
child 248058 8f01b41b169e42bc7f5094acef78fa9f8686f493
push id28888
push userkwierso@gmail.com
push dateThu, 11 Jun 2015 01:29:45 +0000
treeherdermozilla-central@04c057942da4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1169994
milestone41.0a1
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 1169994 Fix Cache to close connection on right thread when init is canceled. r=ehsan
dom/cache/Context.cpp
--- a/dom/cache/Context.cpp
+++ b/dom/cache/Context.cpp
@@ -107,24 +107,28 @@ public:
     MOZ_ASSERT(!mConnection);
     mConnection = aConn;
     MOZ_ASSERT(mConnection);
   }
 
 private:
   ~Data()
   {
-    if (mConnection) {
-      NS_ProxyRelease(mTarget, mConnection);
-    }
+    // We could proxy release our data here, but instead just assert.  The
+    // Context code should guarantee that we are destroyed on the target
+    // thread.  If we're not, then QuotaManager might race and try to clear the
+    // origin out from under us.
+    MOZ_ASSERT(mTarget == NS_GetCurrentThread());
   }
 
   nsCOMPtr<nsIThread> mTarget;
   nsCOMPtr<mozIStorageConnection> mConnection;
 
+  // Threadsafe counting because we're created on the PBackground thread
+  // and destroyed on the target IO thread.
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Context::Data)
 };
 
 // Executed to perform the complicated dance of steps necessary to initialize
 // the QuotaManager.  This must be performed for each origin before any disk
 // IO occurrs.
 class Context::QuotaInitRunnable final : public nsIRunnable
 {
@@ -416,16 +420,18 @@ Context::QuotaInitRunnable::Run()
 
       mState = STATE_RUNNING;
 
       // Execute the provided initialization Action.  The Action must Resolve()
       // before returning.
       mInitAction->RunOnTarget(resolver, mQuotaInfo, mData);
       MOZ_ASSERT(resolver->Resolved());
 
+      mData = nullptr;
+
       break;
     }
     // -------------------
     case STATE_COMPLETING:
     {
       NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
       if (mInitAction) {
         mInitAction->CompleteOnInitiatingThread(mResult);
@@ -910,16 +916,17 @@ Context::CancelForCacheId(CacheId aCache
     }
   }
 }
 
 Context::~Context()
 {
   NS_ASSERT_OWNINGTHREAD(Context);
   MOZ_ASSERT(mManager);
+  MOZ_ASSERT(!mData);
 
   if (mThreadsafeHandle) {
     mThreadsafeHandle->ContextDestroyed(this);
   }
 
   mManager->RemoveContext(this);
 
   if (mNextContext) {