bug 1439383 - clean up the load loadable roots thread when we're done with it r?froydnj,jcj
MozReview-Commit-ID: J5GnpwxYguz
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -947,16 +947,33 @@ LoadLoadableRootsTask::Dispatch()
}
// NB: If anything in this function can cause an acquisition of
// nsNSSComponent::mMutex, this can potentially deadlock with
// nsNSSComponent::Shutdown.
NS_IMETHODIMP
LoadLoadableRootsTask::Run()
{
+ // First we Run() on the "LoadRoots" thread, do our work, and then we Run()
+ // again on the main thread so we can shut down the thread (since we don't
+ // need it any more). We can't shut down the thread while we're *on* the
+ // thread, which is why we do the dispatch to the main thread. CryptoTask.cpp
+ // (which informs this code) says that we can't null out mThread. This appears
+ // to be because its refcount could be decreased while this dispatch is being
+ // processed, so it might get prematurely destroyed. I'm not sure this makes
+ // sense but it'll get cleaned up in our destructor anyway, so it's fine to
+ // not null it out here (as long as we don't run twice on the main thread,
+ // which shouldn't be possible).
+ if (NS_IsMainThread()) {
+ if (mThread) {
+ mThread->Shutdown();
+ }
+ return NS_OK;
+ }
+
nsresult rv = LoadLoadableRoots();
if (NS_FAILED(rv)) {
MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("LoadLoadableRoots failed"));
// We don't return rv here because then BlockUntilLoadableRootsLoaded will
// just wait forever. Instead we'll save its value (below) so we can inform
// code that relies on the roots module being present that loading it
// failed.
}
@@ -974,17 +991,19 @@ LoadLoadableRootsTask::Run()
// Cache the result of LoadLoadableRoots so BlockUntilLoadableRootsLoaded
// can return it to all callers later.
mNSSComponent->mLoadableRootsLoadedResult = rv;
rv = mNSSComponent->mLoadableRootsLoadedMonitor.NotifyAll();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
- return NS_OK;
+
+ // Go back to the main thread to clean up this worker thread.
+ return NS_DispatchToMainThread(this);
}
nsresult
nsNSSComponent::HasActiveSmartCards(bool& result)
{
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
if (!NS_IsMainThread()) {
return NS_ERROR_NOT_SAME_THREAD;