summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjar@google.com <jar@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-30 07:50:53 +0000
committerjar@google.com <jar@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-30 07:50:53 +0000
commitb8f2fe5d397256a8a5d35c9e9b8c84379c5e496e (patch)
tree6f692f7c69497506572c3ab4f5a3e73229046dea
parent7622bd0c36e11b0108d3a8dd256211c05ddf5ff5 (diff)
downloadchromium_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.cc72
-rw-r--r--base/message_loop.h29
-rw-r--r--chrome/common/ipc_sync_channel.cc7
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 {