Bug 1501196 - Ensure RuntimeService::Shutdown() is always called. r=baku a=reland
authorRyan Hunt <rhunt@eqrion.net>
Tue, 30 Oct 2018 11:51:12 -0500
changeset 500336 182a1b088330
parent 500335 a0aeeebfeb68
child 500393 b953c577afe2
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, reland
bugs1501196
milestone65.0a1
first release with
nightly linux32
182a1b088330 / 65.0a1 / 20181101151140 / files
nightly linux64
182a1b088330 / 65.0a1 / 20181101151140 / files
nightly mac
182a1b088330 / 65.0a1 / 20181101151140 / files
nightly win32
182a1b088330 / 65.0a1 / 20181101151140 / files
nightly win64
182a1b088330 / 65.0a1 / 20181101151140 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1501196 - Ensure RuntimeService::Shutdown() is always called. r=baku a=reland It's possible for RuntimeService to be created after 'xpcom-shutdown' has fired. In this case, it will receive 'xpcom-shutdown-threads' and perform Cleanup() but not Shutdown(). This means that mShuttingDown will not be set to 'true', but mIdleThreadTimer will be destroyed. This can cause crashes if a NoteIdleThread callback runs after Cleanup(). This has been observed to happen in xpcshell tests. I think the easiest way to handle this is to manually call Shutdown() in Cleanup() when we see that mShuttingDown == false. This means that Shutdown() might be called in GetOrCreateService() if we fail to create the service, but it looks like the code can handle this. Differential Revision: https://phabricator.services.mozilla.com/D10288
dom/workers/RuntimeService.cpp
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2021,16 +2021,20 @@ RuntimeService::CrashIfHanging()
 
 // This spins the event loop until all workers are finished and their threads
 // have been joined.
 void
 RuntimeService::Cleanup()
 {
   AssertIsOnMainThread();
 
+  if (!mShuttingDown) {
+    Shutdown();
+  }
+
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_WARNING_ASSERTION(obs, "Failed to get observer service?!");
 
   if (mIdleThreadTimer) {
     if (NS_FAILED(mIdleThreadTimer->Cancel())) {
       NS_WARNING("Failed to cancel idle timer!");
     }
     mIdleThreadTimer = nullptr;