Bug 1204784: Do not shut the main thread down before all outstanding asynchronous thread shutdowns complete. r=froydnj

--HG--
extra : rebase_source : 9f4c8a219e2fa6dfbfec78f9f390726f2f07f683
This commit is contained in:
Kyle Huey 2016-01-18 09:34:38 -08:00
parent f20249c9de
commit a80e57e854
3 changed files with 20 additions and 4 deletions

View File

@ -403,6 +403,9 @@ nsThread::ThreadFunc(void* aArg)
BackgroundChild::CloseForCurrentThread();
#endif // defined(MOZILLA_XPCOMRT_API)
// NB: The main thread does not shut down here! It shuts down via
// nsThreadManager::Shutdown.
// Do NS_ProcessPendingEvents but with special handling to set
// mEventsAreDoomed atomically with the removal of the last event. The key
// invariant here is that we will never permit PutEvent to succeed if the
@ -411,10 +414,7 @@ nsThread::ThreadFunc(void* aArg)
// as we have outstanding mRequestedShutdownContexts.
while (true) {
// Check and see if we're waiting on any threads.
while (self->mRequestedShutdownContexts.Length()) {
// We can't stop accepting events just yet. Block and check again.
NS_ProcessNextEvent(self, true);
}
self->WaitForAllAsynchronousShutdowns();
{
MutexAutoLock lock(self->mLock);
@ -778,6 +778,14 @@ nsThread::ShutdownComplete(nsThreadShutdownContext* aContext)
aContext->joiningThread->mRequestedShutdownContexts.RemoveElement(aContext));
}
void
nsThread::WaitForAllAsynchronousShutdowns()
{
while (mRequestedShutdownContexts.Length()) {
NS_ProcessNextEvent(this, true);
}
}
NS_IMETHODIMP
nsThread::Shutdown()
{

View File

@ -76,6 +76,8 @@ public:
void ShutdownComplete(struct nsThreadShutdownContext* aContext);
void WaitForAllAsynchronousShutdowns();
protected:
class nsChainedEventQueue;

View File

@ -155,6 +155,12 @@ nsThreadManager::Shutdown()
}
}
// NB: It's possible that there are events in the queue that want to *start*
// an asynchronous shutdown. But we have already shutdown the threads above,
// so there's no need to worry about them. We only have to wait for all
// in-flight asynchronous thread shutdowns to complete.
mMainThread->WaitForAllAsynchronousShutdowns();
// In case there are any more events somehow...
NS_ProcessPendingEvents(mMainThread);