Bug 1351655 - Log which SharedThreadPools are not yet destroyed on shutdown-threads. r?froydnj draft
authorAndreas Pehrson <pehrsons@mozilla.com>
Tue, 23 Jan 2018 11:40:37 +0100 (2018-01-23)
changeset 749440 279fc682866b8e9039eb0e70c4a6766e40d67248
parent 748520 9a3b6d64a64b328ed0de3d6503b99f20d1c94cfb
push id97399
push userbmo:apehrson@mozilla.com
push dateWed, 31 Jan 2018 13:56:52 +0000 (2018-01-31)
reviewersfroydnj
bugs1351655
milestone60.0a1
Bug 1351655 - Log which SharedThreadPools are not yet destroyed on shutdown-threads. r?froydnj We risk a shutdown hang without any clues if a dangling reference somewhere keeps a SharedThreadPool alive past xpcom-shutdown-threads. This because xpcom-shutdown-threads waits for all SharedThreadPool to be destroyed before advancing shutdown further. nsCycleCollector::Shutdown comes after xpcom-shutdown-threads so it is possible that a reference-cycle unexpectedly keeps a SharedThreadPool alive and blocks shutdown indefinitely. This patch attempts to help diagnose future cases like this by printing which SharedThreadPools we are going to wait for to stderr. MozReview-Commit-ID: CwTApYUMikA
xpcom/threads/SharedThreadPool.cpp
--- a/xpcom/threads/SharedThreadPool.cpp
+++ b/xpcom/threads/SharedThreadPool.cpp
@@ -41,16 +41,29 @@ protected:
 
 NS_IMPL_ISUPPORTS(SharedThreadPoolShutdownObserver, nsIObserver, nsISupports)
 
 NS_IMETHODIMP
 SharedThreadPoolShutdownObserver::Observe(nsISupports* aSubject, const char *aTopic,
                                           const char16_t *aData)
 {
   MOZ_RELEASE_ASSERT(!strcmp(aTopic, "xpcom-shutdown-threads"));
+#ifdef EARLY_BETA_OR_EARLIER
+  {
+    ReentrantMonitorAutoEnter mon(*sMonitor);
+    if (!sPools->Iter().Done()) {
+      nsAutoCString str;
+      for (auto i = sPools->Iter(); !i.Done(); i.Next()) {
+        str.AppendPrintf("\"%s\" ", nsAutoCString(i.Key()).get());
+      }
+      printf_stderr("SharedThreadPool in xpcom-shutdown-threads. Waiting for "
+                    "pools %s\n", str.get());
+    }
+  }
+#endif
   SharedThreadPool::SpinUntilEmpty();
   sMonitor = nullptr;
   sPools = nullptr;
   return NS_OK;
 }
 
 void
 SharedThreadPool::InitStatics()