• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2006-2008 The Chromium Authors
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/auto_reset.h"
8 #include "base/logging.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "build/build_config.h"
11 
12 #if BUILDFLAG(IS_APPLE)
13 #include <mach/thread_policy.h>
14 
15 #include "base/apple/mach_logging.h"
16 #include "base/apple/scoped_mach_port.h"
17 #include "base/apple/scoped_nsautorelease_pool.h"
18 #include "base/threading/threading_features.h"
19 #endif
20 
21 namespace base {
22 
MessagePumpDefault()23 MessagePumpDefault::MessagePumpDefault()
24     : keep_running_(true),
25       event_(WaitableEvent::ResetPolicy::AUTOMATIC,
26              WaitableEvent::InitialState::NOT_SIGNALED) {
27   event_.declare_only_used_while_idle();
28 }
29 
30 MessagePumpDefault::~MessagePumpDefault() = default;
31 
Run(Delegate * delegate)32 void MessagePumpDefault::Run(Delegate* delegate) {
33   AutoReset<bool> auto_reset_keep_running(&keep_running_, true);
34 
35   for (;;) {
36 #if BUILDFLAG(IS_APPLE)
37     apple::ScopedNSAutoreleasePool autorelease_pool;
38 #endif
39 
40     Delegate::NextWorkInfo next_work_info = delegate->DoWork();
41     bool has_more_immediate_work = next_work_info.is_immediate();
42     if (!keep_running_)
43       break;
44 
45     if (has_more_immediate_work)
46       continue;
47 
48     delegate->DoIdleWork();
49     if (!keep_running_)
50       break;
51 
52     if (next_work_info.delayed_run_time.is_max()) {
53       event_.Wait();
54     } else {
55       event_.TimedWait(next_work_info.remaining_delay());
56     }
57     // Since event_ is auto-reset, we don't need to do anything special here
58     // other than service each delegate method.
59   }
60 }
61 
Quit()62 void MessagePumpDefault::Quit() {
63   keep_running_ = false;
64 }
65 
ScheduleWork()66 void MessagePumpDefault::ScheduleWork() {
67   // Since this can be called on any thread, we need to ensure that our Run
68   // loop wakes up.
69   event_.Signal();
70 }
71 
ScheduleDelayedWork(const Delegate::NextWorkInfo & next_work_info)72 void MessagePumpDefault::ScheduleDelayedWork(
73     const Delegate::NextWorkInfo& next_work_info) {
74   // Since this is always called from the same thread as Run(), there is nothing
75   // to do as the loop is already running. It will wait in Run() with the
76   // correct timeout when it's out of immediate tasks.
77   // TODO(gab): Consider removing ScheduleDelayedWork() when all pumps function
78   // this way (bit.ly/merge-message-pump-do-work).
79 }
80 
81 }  // namespace base
82