Bug 779721. Part 4: Fix lock ordering inversion when running control messages during a forced shutdown. r=jesup

This commit is contained in:
Robert O'Callahan 2012-08-01 00:17:22 +12:00
parent 535a1d2f48
commit 481c2bc36d

View File

@ -1413,6 +1413,10 @@ MediaStreamGraphImpl::RunInStableState()
NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
nsTArray<nsCOMPtr<nsIRunnable> > runnables;
// When we're doing a forced shutdown, pending control messages may be
// run on the main thread via RunDuringShutdown. Those messages must
// run without the graph monitor being held. So, we collect them here.
nsTArray<nsAutoPtr<ControlMessage> > controlMessagesToRunDuringShutdown;
{
MonitorAutoLock lock(mMonitor);
@ -1428,17 +1432,13 @@ MediaStreamGraphImpl::RunInStableState()
mStreamUpdates.Clear();
if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && mForceShutDown) {
// Defer calls to RunDuringShutdown() to happen while mMonitor is not held.
for (PRUint32 i = 0; i < mMessageQueue.Length(); ++i) {
MessageBlock& mb = mMessageQueue[i];
for (PRUint32 j = 0; j < mb.mMessages.Length(); ++j) {
mb.mMessages[j]->RunDuringShutdown();
}
controlMessagesToRunDuringShutdown.MoveElementsFrom(mb.mMessages);
}
mMessageQueue.Clear();
for (PRUint32 i = 0; i < mCurrentTaskMessageQueue.Length(); ++i) {
mCurrentTaskMessageQueue[i]->RunDuringShutdown();
}
mCurrentTaskMessageQueue.Clear();
controlMessagesToRunDuringShutdown.MoveElementsFrom(mCurrentTaskMessageQueue);
// Stop MediaStreamGraph threads. Do not clear gGraph since
// we have outstanding DOM objects that may need it.
mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
@ -1497,6 +1497,9 @@ MediaStreamGraphImpl::RunInStableState()
for (PRUint32 i = 0; i < runnables.Length(); ++i) {
runnables[i]->Run();
}
for (PRUint32 i = 0; i < controlMessagesToRunDuringShutdown.Length(); ++i) {
controlMessagesToRunDuringShutdown[i]->RunDuringShutdown();
}
}
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);