diff options
author | jar@google.com <jar@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-30 07:50:53 +0000 |
---|---|---|
committer | jar@google.com <jar@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-30 07:50:53 +0000 |
commit | b8f2fe5d397256a8a5d35c9e9b8c84379c5e496e (patch) | |
tree | 6f692f7c69497506572c3ab4f5a3e73229046dea | |
parent | 7622bd0c36e11b0108d3a8dd256211c05ddf5ff5 (diff) | |
download | chromium_src-b8f2fe5d397256a8a5d35c9e9b8c84379c5e496e.zip chromium_src-b8f2fe5d397256a8a5d35c9e9b8c84379c5e496e.tar.gz chromium_src-b8f2fe5d397256a8a5d35c9e9b8c84379c5e496e.tar.bz2 |
Rollback 109
M base/message_loop.h
M base/message_loop.cc
M chrome/common/ipc_sync_channel.cc
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/message_loop.cc | 72 | ||||
-rw-r--r-- | base/message_loop.h | 29 | ||||
-rw-r--r-- | chrome/common/ipc_sync_channel.cc | 7 |
3 files changed, 48 insertions, 60 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc index ccaf700..623ec99 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -169,15 +169,7 @@ void MessageLoop::RemoveObserver(Observer *obs) { } void MessageLoop::Run() { - RunHandler(NULL, false); -} - -void MessageLoop::Run(Dispatcher* dispatcher) { - RunHandler(dispatcher, false); -} - -void MessageLoop::RunOnce() { - RunHandler(NULL, true); + Run(NULL); } // Runs the loop in two different SEH modes: @@ -185,19 +177,20 @@ void MessageLoop::RunOnce() { // one that calls SetUnhandledExceptionFilter(). // enable_SEH_restoration_ = true : any unhandled exception goes to the filter // that was existed before the loop was run. -void MessageLoop::RunHandler(Dispatcher* dispatcher, bool run_loop_once) { +void MessageLoop::Run(Dispatcher* dispatcher) { if (exception_restoration_) { LPTOP_LEVEL_EXCEPTION_FILTER current_filter = GetTopSEHFilter(); __try { - RunInternal(dispatcher, run_loop_once); + RunInternal(dispatcher); } __except(SEHFilter(current_filter)) { } } else { - RunInternal(dispatcher, run_loop_once); + RunInternal(dispatcher); } } //------------------------------------------------------------------------------ +// Methods supporting various strategies for servicing the numerous queues. // IF this was just a simple PeekMessage() loop (servicing all passible work // queues), then Windows would try to achieve the following order according to // MSDN documentation about PeekMessage with no filter): @@ -210,7 +203,7 @@ void MessageLoop::RunHandler(Dispatcher* dispatcher, bool run_loop_once) { // Summary: none of the above classes is starved, and sent messages has twice // the chance of being processed (i.e., reduced service time). -void MessageLoop::RunInternal(Dispatcher* dispatcher, bool run_loop_once) { +void MessageLoop::RunInternal(Dispatcher* dispatcher) { // Preserve ability to be called recursively. ScopedStateSave save(this); // State is restored on exit. dispatcher_ = dispatcher; @@ -218,30 +211,38 @@ void MessageLoop::RunInternal(Dispatcher* dispatcher, bool run_loop_once) { DCHECK(this == current()); // - // Process pending messages and signaled objects. + // Process all pending messages and signaled objects. // // Flush these queues before exiting due to a kMsgQuit or else we risk not // shutting down properly as some operations may depend on further event // processing. (Note: some tests may use quit_now_ to exit more swiftly, // and leave messages pending, so don't assert the above fact). - RunTraditional(run_loop_once); - DCHECK(run_loop_once || quit_received_ || quit_now_); + // + + RunTraditional(); + DCHECK(quit_received_ || quit_now_); } -void MessageLoop::RunTraditional(bool run_loop_once) { - do { +typedef bool (MessageLoop::*ProcessingMethod)(); +typedef ProcessingMethod ProcessingMethods[]; + +void MessageLoop::RunTraditional() { + run_depth_++; + for (;;) { // If we do any work, we may create more messages etc., and more work - // may possibly be waiting in another task group. When we (for example) - // ProcessNextWindowsMessage(), there is a good chance there are still more - // messages waiting (same thing for ProcessNextObject(), which responds to - // only one signaled object; etc.). On the other hand, when any of these - // methods return having done no work, then it is pretty unlikely that - // calling them again quickly will find any work to do. + // may possibly be waiting in another task group. In addition, each method + // call here typically limits work to 1 (worst case 2) items. As a result, + // when we (for example) ProcessNextWindowsMessage() there is a good chance + // there are still more waiting (same thing for ProcessNextDeferredTask(), + // which responds to only one signaled object.). On the other hand, when + // any of these methods return having done no work, then it is pretty + // unlikely that calling them again quickly will find any work to do. // Finally, if they all say they had no work, then it is a good time to // consider sleeping (waiting) for more work. - bool more_work_is_plausible = ProcessNextWindowsMessage(); + bool more_work_is_plausible = false; + more_work_is_plausible |= ProcessNextWindowsMessage(); if (quit_now_) - return; + break; more_work_is_plausible |= ProcessNextDeferredTask(); more_work_is_plausible |= ProcessNextObject(); @@ -249,7 +250,7 @@ void MessageLoop::RunTraditional(bool run_loop_once) { continue; if (quit_received_) - return; + break; // Run any timer that is ready to run. It may create messages etc. if (ProcessSomeTimers()) @@ -257,19 +258,16 @@ void MessageLoop::RunTraditional(bool run_loop_once) { // We run delayed non nestable tasks only after all nestable tasks have // run, to preserve FIFO ordering. - if (ProcessNextDelayedNonNestableTask()) + more_work_is_plausible = ProcessNextDelayedNonNestableTask(); + if (more_work_is_plausible) continue; - if (run_loop_once) - return; - // We service APCs in WaitForWork, without returning. WaitForWork(); // Wait (sleep) until we have work to do again. - } while (!run_loop_once); -} + } -//------------------------------------------------------------------------------ -// Wrapper functions for use in above message loop framework. + run_depth_--; +} bool MessageLoop::ProcessNextDelayedNonNestableTask() { if (run_depth_ != 1) @@ -282,6 +280,9 @@ bool MessageLoop::ProcessNextDelayedNonNestableTask() { return true; } +//------------------------------------------------------------------------------ +// Wrapper functions for use in above message loop frameworks. + bool MessageLoop::ProcessNextDeferredTask() { ReloadWorkQueue(); return QueueOrRunTask(NULL); @@ -398,7 +399,6 @@ LRESULT MessageLoop::MessageWndProc(HWND hwnd, UINT message, } case kMsgQuit: { - CHECK(!quit_received_); // Discarding a second quit will cause a hang. quit_received_ = true; return 0; } diff --git a/base/message_loop.h b/base/message_loop.h index ecb7e27..1d1e11b 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -249,12 +249,9 @@ class MessageLoop { PostTask(from_here, new ReleaseTask<T>(object)); } - // Run the message loop. + // Run the message loop void Run(); - // Run just one pass through the message loop. - void RunOnce(); - // See description of Dispatcher for how Run uses Dispatcher. void Run(Dispatcher* dispatcher); @@ -350,14 +347,11 @@ class MessageLoop { : loop_(loop), dispatcher_(loop->dispatcher_), quit_now_(loop->quit_now_), - quit_received_(loop->quit_received_), - run_depth_(loop->run_depth_) { + quit_received_(loop->quit_received_) { loop->quit_now_ = loop->quit_received_ = false; - ++loop->run_depth_; } ~ScopedStateSave() { - loop_->run_depth_ = run_depth_; loop_->quit_received_ = quit_received_; loop_->quit_now_ = quit_now_; loop_->dispatcher_ = dispatcher_; @@ -368,7 +362,6 @@ class MessageLoop { Dispatcher* dispatcher_; bool quit_now_; bool quit_received_; - int run_depth_; }; // struct ScopedStateSave // A prioritized queue with interface that mostly matches std::queue<>. @@ -438,21 +431,15 @@ class MessageLoop { void InitMessageWnd(); - - // A function to encapsulate all the exception handling capability in the - // stacks around the running of a main message loop. + // The actual message loop implementation. Called by all flavors of Run(). // It will run the message loop in a SEH try block or not depending on the // set_SEH_restoration() flag. - void RunHandler(Dispatcher* dispatcher, bool run_loop_once); + void RunInternal(Dispatcher* dispatcher); - // A surrounding stack frame around the running of the message loop that - // supports all saving and restoring of state, as is needed for any/all (ugly) - // recursive calls. - void RunInternal(Dispatcher* dispatcher, bool run_loop_once); - - // An extended message loop (message pump) that loops mostly forever, and - // processes task, signals, timers, etc. - void RunTraditional(bool run_loop_once); + //---------------------------------------------------------------------------- + // A list of alternate message loop priority systems. The strategy_selector_ + // determines which one to actually use. + void RunTraditional(); //---------------------------------------------------------------------------- // A list of method wrappers with identical calling signatures (no arguments) diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc index 1dc106c..bbd7a23 100644 --- a/chrome/common/ipc_sync_channel.cc +++ b/chrome/common/ipc_sync_channel.cc @@ -445,10 +445,11 @@ bool SyncChannel::Send(IPC::Message* message) { // shutdown the nested loop when there are no more messages. pump_messages_events_.push(pump_messages_event); bool old_state = MessageLoop::current()->NestableTasksAllowed(); + // Insert a Quit message so that we just flush the MessageLoop without + // letting the MessageLoop wait for more messages. + MessageLoop::current()->Quit(); MessageLoop::current()->SetNestableTasksAllowed(true); - // Process a message, but come right back out of the MessageLoop (don't - // loop, sleep, or wait for a kMsgQuit). - MessageLoop::current()->RunOnce(); + MessageLoop::current()->Run(); MessageLoop::current()->SetNestableTasksAllowed(old_state); pump_messages_events_.pop(); } else { |