Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/message_pump_default.h"
7 #include "base/logging.h"
8 #include "base/message_loop.h"
9 #include "base/scoped_nsautorelease_pool.h"
10 #include "GeckoProfiler.h"
12 #include "mozilla/BackgroundHangMonitor.h"
14 namespace base {
16 MessagePumpDefault::MessagePumpDefault()
17 : keep_running_(true),
18 event_(false, false) {
19 }
21 void MessagePumpDefault::Run(Delegate* delegate) {
22 DCHECK(keep_running_) << "Quit must have been called outside of Run!";
24 const MessageLoop* const loop = MessageLoop::current();
25 mozilla::BackgroundHangMonitor hangMonitor(
26 loop->thread_name().c_str(),
27 loop->transient_hang_timeout(),
28 loop->permanent_hang_timeout());
30 for (;;) {
31 ScopedNSAutoreleasePool autorelease_pool;
33 hangMonitor.NotifyActivity();
34 bool did_work = delegate->DoWork();
35 if (!keep_running_)
36 break;
38 hangMonitor.NotifyActivity();
39 did_work |= delegate->DoDelayedWork(&delayed_work_time_);
40 if (!keep_running_)
41 break;
43 if (did_work)
44 continue;
46 hangMonitor.NotifyActivity();
47 did_work = delegate->DoIdleWork();
48 if (!keep_running_)
49 break;
51 if (did_work)
52 continue;
54 if (delayed_work_time_.is_null()) {
55 hangMonitor.NotifyWait();
56 PROFILER_LABEL("MessagePump", "Wait");
57 {
58 GeckoProfilerSleepRAII profiler_sleep;
59 event_.Wait();
60 }
61 } else {
62 TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
63 if (delay > TimeDelta()) {
64 hangMonitor.NotifyWait();
65 PROFILER_LABEL("MessagePump", "Wait");
66 {
67 GeckoProfilerSleepRAII profiler_sleep;
68 event_.TimedWait(delay);
69 }
70 } else {
71 // It looks like delayed_work_time_ indicates a time in the past, so we
72 // need to call DoDelayedWork now.
73 delayed_work_time_ = TimeTicks();
74 }
75 }
76 // Since event_ is auto-reset, we don't need to do anything special here
77 // other than service each delegate method.
78 }
80 keep_running_ = true;
81 }
83 void MessagePumpDefault::Quit() {
84 keep_running_ = false;
85 }
87 void MessagePumpDefault::ScheduleWork() {
88 // Since this can be called on any thread, we need to ensure that our Run
89 // loop wakes up.
90 event_.Signal();
91 }
93 void MessagePumpDefault::ScheduleDelayedWork(
94 const TimeTicks& delayed_work_time) {
95 // We know that we can't be blocked on Wait right now since this method can
96 // only be called on the same thread as Run, so we only need to update our
97 // record of how long to sleep when we do sleep.
98 delayed_work_time_ = delayed_work_time;
99 }
101 } // namespace base