• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "base/message_loop/message_pump_default.h"
6 
7 #include "base/logging.h"
8 #include "base/threading/thread_restrictions.h"
9 #include "build/build_config.h"
10 
11 #if defined(OS_MACOSX)
12 #include "base/mac/scoped_nsautorelease_pool.h"
13 #endif
14 
15 namespace base {
16 
MessagePumpDefault()17 MessagePumpDefault::MessagePumpDefault()
18     : keep_running_(true),
19       event_(false, false) {
20 }
21 
~MessagePumpDefault()22 MessagePumpDefault::~MessagePumpDefault() {
23 }
24 
Run(Delegate * delegate)25 void MessagePumpDefault::Run(Delegate* delegate) {
26   DCHECK(keep_running_) << "Quit must have been called outside of Run!";
27 
28   for (;;) {
29 #if defined(OS_MACOSX)
30     mac::ScopedNSAutoreleasePool autorelease_pool;
31 #endif
32 
33     bool did_work = delegate->DoWork();
34     if (!keep_running_)
35       break;
36 
37     did_work |= delegate->DoDelayedWork(&delayed_work_time_);
38     if (!keep_running_)
39       break;
40 
41     if (did_work)
42       continue;
43 
44     did_work = delegate->DoIdleWork();
45     if (!keep_running_)
46       break;
47 
48     if (did_work)
49       continue;
50 
51     ThreadRestrictions::ScopedAllowWait allow_wait;
52     if (delayed_work_time_.is_null()) {
53       event_.Wait();
54     } else {
55       TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
56       if (delay > TimeDelta()) {
57         event_.TimedWait(delay);
58       } else {
59         // It looks like delayed_work_time_ indicates a time in the past, so we
60         // need to call DoDelayedWork now.
61         delayed_work_time_ = TimeTicks();
62       }
63     }
64     // Since event_ is auto-reset, we don't need to do anything special here
65     // other than service each delegate method.
66   }
67 
68   keep_running_ = true;
69 }
70 
Quit()71 void MessagePumpDefault::Quit() {
72   keep_running_ = false;
73 }
74 
ScheduleWork()75 void MessagePumpDefault::ScheduleWork() {
76   // Since this can be called on any thread, we need to ensure that our Run
77   // loop wakes up.
78   event_.Signal();
79 }
80 
ScheduleDelayedWork(const TimeTicks & delayed_work_time)81 void MessagePumpDefault::ScheduleDelayedWork(
82     const TimeTicks& delayed_work_time) {
83   // We know that we can't be blocked on Wait right now since this method can
84   // only be called on the same thread as Run, so we only need to update our
85   // record of how long to sleep when we do sleep.
86   delayed_work_time_ = delayed_work_time;
87 }
88 
89 }  // namespace base
90