Bug 784647: Ensure that Tasks and XPCOM events are dispatched with the same priority. r=bent

This commit is contained in:
Chris Jones 2012-08-25 01:25:08 -07:00
parent d82d1d5e65
commit 384aad9cbe

View File

@ -83,9 +83,10 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
if (!keep_running_)
break;
did_work |= aDelegate->DoWork();
if (!keep_running_)
break;
// NB: it is crucial *not* to directly call |aDelegate->DoWork()|
// here. To ensure that MessageLoop tasks and XPCOM events have
// equal priority, we sensitively rely on processing exactly one
// Task per DoWorkRunnable XPCOM event.
#ifdef MOZ_WIDGET_ANDROID
// This processes messages in the Android Looper. Note that we only
@ -207,6 +208,25 @@ MessagePumpForChildProcess::Run(MessagePump::Delegate* aDelegate)
#ifdef DEBUG
NS_ASSERTION(aDelegate && aDelegate == gFirstDelegate, "Huh?!");
#endif
// We can get to this point in startup with Tasks in our loop's
// incoming_queue_ or pending_queue_, but without a matching
// DoWorkRunnable(). In MessagePump::Run() above, we sensitively
// depend on *not* directly calling delegate->DoWork(), because that
// prioritizes Tasks above XPCOM events. However, from this point
// forward, any Task posted to our loop is guaranteed to have a
// DoWorkRunnable enqueued for it.
//
// So we just flush the pending work here and move on.
MessageLoop* loop = MessageLoop::current();
bool nestableTasksAllowed = loop->NestableTasksAllowed();
loop->SetNestableTasksAllowed(true);
while (aDelegate->DoWork());
loop->SetNestableTasksAllowed(nestableTasksAllowed);
// Really run.
mozilla::ipc::MessagePump::Run(aDelegate);
}