Bug 1388998 - mozStorageService connection unregistering should defer final Release(). r=mak
☠☠ backed out by ff5340cbaef0 ☠ ☠
authorAndrew Sutherland <asutherland@asutherland.org>
Fri, 29 Sep 2017 20:05:38 -0400
changeset 437254 0a5a34ef66d11be4c0b64e873e05d84896f3a994
parent 437253 508556cd3d2aa3bab0796e5da4fc0656b1342621
child 437255 0ad5ea4a3f1cda04e949cdae7e2c22f54d44d476
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1388998
milestone58.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 1388998 - mozStorageService connection unregistering should defer final Release(). r=mak NS_ProxyRelease will immediately release the provided reference if already on the right thread unless aAlwaysRelease=true (the default is false). We need to set it to be true to avoid Close() and its potential to, out of desperation when faced with misuse, spin a nested event loop.
storage/mozStorageService.cpp
--- a/storage/mozStorageService.cpp
+++ b/storage/mozStorageService.cpp
@@ -304,18 +304,25 @@ Service::unregisterConnection(Connection
 
     for (uint32_t i = 0 ; i < mConnections.Length(); ++i) {
       if (mConnections[i] == aConnection) {
         nsCOMPtr<nsIThread> thread = mConnections[i]->threadOpenedOn;
 
         // Ensure the connection is released on its opening thread.  Note, we
         // must use .forget().take() so that we can manually cast to an
         // unambiguous nsISupports type.
+        //
+        // We specify aAlwaysProxy=true because if we don't, the destructor for
+        // the connection will be invoked if the connection is owned by the
+        // main thread.  And since the Connection destructor calls Close() and
+        // that may in turn call SpinningSynchronousClose() if the connection
+        // was not properly shutdown, that can lead to re-entrancy problems.
         NS_ProxyRelease(
-          "storage::Service::mConnections", thread, mConnections[i].forget());
+          "storage::Service::mConnections", thread, mConnections[i].forget(),
+          true);
 
         mConnections.RemoveElementAt(i);
         return;
       }
     }
 
     MOZ_ASSERT_UNREACHABLE("Attempt to unregister unknown storage connection!");
   }