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