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