Bug 1208957 - Join the watchdog thread to avoid shutdown races. r=billm
authorBlake Kaplan <mrbkap@gmail.com>
Tue, 14 Mar 2017 23:27:21 -0700
changeset 347874 10a3d094cfc1550200f8699f0e4ca3b1327fce68
parent 347873 0b51e2a9d7810cc12363afe41aef50a089cbca10
child 347875 9ba55f98e3bf3e1db1257a0a5a1a5d77494e2f7d
push id38952
push usermrbkap@mozilla.com
push dateWed, 15 Mar 2017 22:30:15 +0000
treeherderautoland@9ba55f98e3bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1208957
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1208957 - Join the watchdog thread to avoid shutdown races. r=billm MozReview-Commit-ID: FlnPO2fJWVu
js/xpconnect/src/XPCJSContext.cpp
--- a/js/xpconnect/src/XPCJSContext.cpp
+++ b/js/xpconnect/src/XPCJSContext.cpp
@@ -967,19 +967,22 @@ class Watchdog
             NS_RUNTIMEABORT("PR_NewLock failed.");
         mWakeup = PR_NewCondVar(mLock);
         if (!mWakeup)
             NS_RUNTIMEABORT("PR_NewCondVar failed.");
 
         {
             AutoLockWatchdog lock(this);
 
+            // Gecko uses thread private for accounting and has to clean up at thread exit.
+            // Therefore, even though we don't have a return value from the watchdog, we need to
+            // join it on shutdown.
             mThread = PR_CreateThread(PR_USER_THREAD, WatchdogMain, this,
                                       PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
-                                      PR_UNJOINABLE_THREAD, 0);
+                                      PR_JOINABLE_THREAD, 0);
             if (!mThread)
                 NS_RUNTIMEABORT("PR_CreateThread failed!");
 
             // WatchdogMain acquires the lock and then asserts mInitialized. So
             // make sure to set mInitialized before releasing the lock here so
             // that it's atomic with the creation of the thread.
             mInitialized = true;
         }
@@ -996,16 +999,18 @@ class Watchdog
             mShuttingDown = true;
 
             // Wake up the watchdog, and wait for it to call us back.
             PR_NotifyCondVar(mWakeup);
             PR_WaitCondVar(mWakeup, PR_INTERVAL_NO_TIMEOUT);
             MOZ_ASSERT(!mShuttingDown);
         }
 
+        PR_JoinThread(mThread);
+
         // Destroy state.
         mThread = nullptr;
         PR_DestroyCondVar(mWakeup);
         mWakeup = nullptr;
         PR_DestroyLock(mLock);
         mLock = nullptr;
 
         // All done.