From b16ef312cb28582a1d324d20e4328afeef2c7538 Mon Sep 17 00:00:00 2001 From: "darin@google.com" Date: Tue, 19 Aug 2008 18:36:23 +0000 Subject: Define MessagePumpDefault and use it to implement MessageLoop on non-Windows platforms. This is actually just a first-step toward the real fix which is to use MessagePumpDefault on all platforms on non-UI and non-IO threads. This CL also fixes some GCC compilation errors. I renamed MessageLoopOwnable to TaskBase, which seems more appropriate since a MessageLoopOwnable has a next Task pointer and clearly is only meaningful in the context of Task. (I wonder why it is even a separate class, but that is another issue.) I had to make the next_task / set_next_task methods public since they are used by an inner class of MessageLoop. Perhaps those inner classes should be made into top-level classes, but that seemed like too much to change at this time. R=jar,mmentovai git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1045 0039d316-1c4b-4281-b951-d872f2087c98 --- base/message_pump_default.cc | 100 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 base/message_pump_default.cc (limited to 'base/message_pump_default.cc') diff --git a/base/message_pump_default.cc b/base/message_pump_default.cc new file mode 100644 index 0000000..916d035 --- /dev/null +++ b/base/message_pump_default.cc @@ -0,0 +1,100 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "base/message_pump_default.h" + +#include "base/logging.h" +#include "base/time.h" + +namespace base { + +MessagePumpDefault::MessagePumpDefault() + : keep_running_(true), + event_(false, false) { +} + +void MessagePumpDefault::Run(Delegate* delegate) { + DCHECK(keep_running_) << "Quit must have been called outside of Run!"; + + for (;;) { + bool did_work = delegate->DoWork(); + if (!keep_running_) + break; + if (did_work) + continue; + + // TODO(darin): Delayed work will be starved if DoWork continues to return + // true. We should devise a better strategy. + + TimeDelta delay; + did_work = delegate->DoDelayedWork(&delay); + if (!keep_running_) + break; + if (did_work) + continue; + + did_work = delegate->DoIdleWork(); + if (!keep_running_) + break; + if (did_work) + continue; + // When DoIdleWork does not work, we also assume that it ran very quickly + // such that |delay| still properly indicates how long we are to sleep. + + if (delay < TimeDelta::FromMilliseconds(0)) { + event_.Wait(); + } else { + event_.TimedWait(delay); + } + // Since event_ is auto-reset, we don't need to do anything special here + // other than service each delegate method. + } + + keep_running_ = true; +} + +void MessagePumpDefault::Quit() { + keep_running_ = false; +} + +void MessagePumpDefault::ScheduleWork() { + // Since this can be called on any thread, we need to ensure that our Run + // loop wakes up. + event_.Signal(); +} + +void MessagePumpDefault::ScheduleDelayedWork(const TimeDelta& delay) { + // We know that we can't be blocked on Wait right now since this method can + // only be called on the same thread as Run, but to ensure that when we do + // sleep, we sleep for the right time, we signal the event to cause the Run + // loop to do one more iteration. + event_.Signal(); +} + +} // namespace base -- cgit v1.1