1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/message_pump_default.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,101 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/message_pump_default.h" 1.9 + 1.10 +#include "base/logging.h" 1.11 +#include "base/message_loop.h" 1.12 +#include "base/scoped_nsautorelease_pool.h" 1.13 +#include "GeckoProfiler.h" 1.14 + 1.15 +#include "mozilla/BackgroundHangMonitor.h" 1.16 + 1.17 +namespace base { 1.18 + 1.19 +MessagePumpDefault::MessagePumpDefault() 1.20 + : keep_running_(true), 1.21 + event_(false, false) { 1.22 +} 1.23 + 1.24 +void MessagePumpDefault::Run(Delegate* delegate) { 1.25 + DCHECK(keep_running_) << "Quit must have been called outside of Run!"; 1.26 + 1.27 + const MessageLoop* const loop = MessageLoop::current(); 1.28 + mozilla::BackgroundHangMonitor hangMonitor( 1.29 + loop->thread_name().c_str(), 1.30 + loop->transient_hang_timeout(), 1.31 + loop->permanent_hang_timeout()); 1.32 + 1.33 + for (;;) { 1.34 + ScopedNSAutoreleasePool autorelease_pool; 1.35 + 1.36 + hangMonitor.NotifyActivity(); 1.37 + bool did_work = delegate->DoWork(); 1.38 + if (!keep_running_) 1.39 + break; 1.40 + 1.41 + hangMonitor.NotifyActivity(); 1.42 + did_work |= delegate->DoDelayedWork(&delayed_work_time_); 1.43 + if (!keep_running_) 1.44 + break; 1.45 + 1.46 + if (did_work) 1.47 + continue; 1.48 + 1.49 + hangMonitor.NotifyActivity(); 1.50 + did_work = delegate->DoIdleWork(); 1.51 + if (!keep_running_) 1.52 + break; 1.53 + 1.54 + if (did_work) 1.55 + continue; 1.56 + 1.57 + if (delayed_work_time_.is_null()) { 1.58 + hangMonitor.NotifyWait(); 1.59 + PROFILER_LABEL("MessagePump", "Wait"); 1.60 + { 1.61 + GeckoProfilerSleepRAII profiler_sleep; 1.62 + event_.Wait(); 1.63 + } 1.64 + } else { 1.65 + TimeDelta delay = delayed_work_time_ - TimeTicks::Now(); 1.66 + if (delay > TimeDelta()) { 1.67 + hangMonitor.NotifyWait(); 1.68 + PROFILER_LABEL("MessagePump", "Wait"); 1.69 + { 1.70 + GeckoProfilerSleepRAII profiler_sleep; 1.71 + event_.TimedWait(delay); 1.72 + } 1.73 + } else { 1.74 + // It looks like delayed_work_time_ indicates a time in the past, so we 1.75 + // need to call DoDelayedWork now. 1.76 + delayed_work_time_ = TimeTicks(); 1.77 + } 1.78 + } 1.79 + // Since event_ is auto-reset, we don't need to do anything special here 1.80 + // other than service each delegate method. 1.81 + } 1.82 + 1.83 + keep_running_ = true; 1.84 +} 1.85 + 1.86 +void MessagePumpDefault::Quit() { 1.87 + keep_running_ = false; 1.88 +} 1.89 + 1.90 +void MessagePumpDefault::ScheduleWork() { 1.91 + // Since this can be called on any thread, we need to ensure that our Run 1.92 + // loop wakes up. 1.93 + event_.Signal(); 1.94 +} 1.95 + 1.96 +void MessagePumpDefault::ScheduleDelayedWork( 1.97 + const TimeTicks& delayed_work_time) { 1.98 + // We know that we can't be blocked on Wait right now since this method can 1.99 + // only be called on the same thread as Run, so we only need to update our 1.100 + // record of how long to sleep when we do sleep. 1.101 + delayed_work_time_ = delayed_work_time; 1.102 +} 1.103 + 1.104 +} // namespace base