mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1388998 - Drop final Connection reference after finishing guarded connection list mutation. r=mak
--HG-- extra : rebase_source : 1c87e01c114e50fd54f8bf93fc835bd0e58a2d68
This commit is contained in:
parent
b66a653de9
commit
c7ad213382
@ -302,27 +302,38 @@ Service::unregisterConnection(Connection *aConnection)
|
||||
// alive. So ensure that Service is destroyed only after the Connection is
|
||||
// cleanly unregistered and destroyed.
|
||||
RefPtr<Service> kungFuDeathGrip(this);
|
||||
RefPtr<Connection> forgettingRef;
|
||||
{
|
||||
mRegistrationMutex.AssertNotCurrentThreadOwns();
|
||||
MutexAutoLock mutex(mRegistrationMutex);
|
||||
|
||||
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.
|
||||
NS_ProxyRelease(
|
||||
"storage::Service::mConnections", thread, mConnections[i].forget());
|
||||
|
||||
// Because dropping the final reference can potentially result in
|
||||
// spinning a nested event loop if the connection was not properly
|
||||
// shutdown, we want to do that outside this loop so that we can finish
|
||||
// mutating the array and drop our mutex.
|
||||
forgettingRef = mConnections[i].forget();
|
||||
mConnections.RemoveElementAt(i);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Attempt to unregister unknown storage connection!");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(forgettingRef,
|
||||
"Attempt to unregister unknown storage connection!");
|
||||
|
||||
// Ensure the connection is released on its opening thread. We explicitly use
|
||||
// aAlwaysDispatch=false because at the time of writing this, LocalStorage's
|
||||
// StorageDBThread uses a hand-rolled PRThread implementation that cannot
|
||||
// handle us dispatching events at it during shutdown. However, it is
|
||||
// arguably also desirable for callers to not be aware of our connection
|
||||
// tracking mechanism. And by synchronously dropping the reference (when
|
||||
// on the correct thread), this avoids surprises for the caller and weird
|
||||
// shutdown edge cases.
|
||||
nsCOMPtr<nsIThread> thread = forgettingRef->threadOpenedOn;
|
||||
NS_ProxyRelease(
|
||||
"storage::Service::mConnections", thread, forgettingRef.forget(), false);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user