bug 1439383 - clean up the load loadable roots thread when we're done with it r?froydnj,jcj draft
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 07 Jun 2018 15:11:49 -0700
changeset 805491 dce03ac771f8789dd916511ce55c99c562646e54
parent 805204 199a085199815cc99daa658956a7c9436e1d436b
push id112683
push userbmo:dkeeler@mozilla.com
push dateThu, 07 Jun 2018 22:12:36 +0000
reviewersfroydnj, jcj
bugs1439383
milestone62.0a1
bug 1439383 - clean up the load loadable roots thread when we're done with it r?froydnj,jcj MozReview-Commit-ID: J5GnpwxYguz
security/manager/ssl/nsNSSComponent.cpp
--- 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;