message_pump_default.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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
14namespace base {
15
16MessagePumpDefault::MessagePumpDefault()
17    : keep_running_(true),
18      event_(false, false) {
19}
20
21MessagePumpDefault::~MessagePumpDefault() {
22}
23
24void 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
70void MessagePumpDefault::Quit() {
71  keep_running_ = false;
72}
73
74void 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
80void 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