Bug 1008254 - Allow Nuwa's global sAllThreads list to be non-empty on exit, to green a near-permanent orange on B2G mochitest-9 - r=khuey, a=sledru
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 02 Jul 2014 16:40:29 -0400
changeset 207622 9146671aac33bc41c3351bfaa57f11f8751c0165
parent 207621 3183bbafb0f42c95140aebca020ee8dee4edca47
child 207623 2bc0bc0e14a3520442f1894608d88b27ce3fcf04
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, sledru
bugs1008254
milestone32.0a2
Bug 1008254 - Allow Nuwa's global sAllThreads list to be non-empty on exit, to green a near-permanent orange on B2G mochitest-9 - r=khuey, a=sledru
mozglue/build/Nuwa.cpp
--- a/mozglue/build/Nuwa.cpp
+++ b/mozglue/build/Nuwa.cpp
@@ -247,19 +247,57 @@ static TLSKeySet sTLSKeys;
  * This mutex is used to block the running threads and freeze their contexts.
  * PrepareNuwaProcess() is the first one to acquire the lock. Further attempts
  * to acquire this mutex (in the freeze point macros) will block and freeze the
  * calling thread.
  */
 static pthread_mutex_t sThreadFreezeLock = PTHREAD_MUTEX_INITIALIZER;
 
 static thread_info_t sMainThread;
-static LinkedList<thread_info_t> sAllThreads;
 static int sThreadCount = 0;
 static int sThreadFreezeCount = 0;
+
+// Bug 1008254: LinkedList's destructor asserts that the list is empty.
+// But here, on exit, when the global sAllThreads list
+// is destroyed, it may or may be empty. Bug 1008254 comment 395 has a log
+// when there were 8 threads remaining on exit. So this assertion was
+// intermittently (almost every second time) failing.
+// As a work-around to avoid this intermittent failure, we clear the list on
+// exit just before it gets destroyed. This is the only purpose of that
+// AllThreadsListType subclass.
+struct AllThreadsListType : public LinkedList<thread_info_t>
+{
+  ~AllThreadsListType()
+  {
+    if (!isEmpty()) {
+      __android_log_print(ANDROID_LOG_WARN, "Nuwa",
+                          "Threads remaining at exit:\n");
+      int n = 0;
+      for (const thread_info_t* t = getFirst(); t; t = t->getNext()) {
+        __android_log_print(ANDROID_LOG_WARN, "Nuwa",
+                            "  %.*s (origNativeThreadID=%d recreatedNativeThreadID=%d)\n",
+                            NATIVE_THREAD_NAME_LENGTH,
+                            t->nativeThreadName,
+                            t->origNativeThreadID,
+                            t->recreatedNativeThreadID);
+        n++;
+      }
+      __android_log_print(ANDROID_LOG_WARN, "Nuwa",
+                          "total: %d outstanding threads. "
+                          "Please fix them so they're destroyed before this point!\n", n);
+      __android_log_print(ANDROID_LOG_WARN, "Nuwa",
+                          "note: sThreadCount=%d, sThreadFreezeCount=%d\n",
+                          sThreadCount,
+                          sThreadFreezeCount);
+    }
+    clear();
+  }
+};
+static AllThreadsListType sAllThreads;
+
 /**
  * This mutex protects the access to thread info:
  * sAllThreads, sThreadCount, sThreadFreezeCount, sRecreateVIPCount.
  */
 static pthread_mutex_t sThreadCountLock = PTHREAD_MUTEX_INITIALIZER;
 /**
  * This condition variable lets MakeNuwaProcess() wait until all recreated
  * threads are frozen.