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_ - TimeTicks::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_ = TimeTicks();
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(
71    const TimeTicks& delayed_work_time) {
72  // We know that we can't be blocked on Wait right now since this method can
73  // only be called on the same thread as Run, so we only need to update our
74  // record of how long to sleep when we do sleep.
75  delayed_work_time_ = delayed_work_time;
76}
77
78}  // namespace base
79