xref: /aosp_15_r20/external/cronet/base/message_loop/message_pump_default.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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     has_more_immediate_work = delegate->DoIdleWork();
49     if (!keep_running_)
50       break;
51 
52     if (has_more_immediate_work)
53       continue;
54 
55     if (next_work_info.delayed_run_time.is_max()) {
56       event_.Wait();
57     } else {
58       event_.TimedWait(next_work_info.remaining_delay());
59     }
60     // Since event_ is auto-reset, we don't need to do anything special here
61     // other than service each delegate method.
62   }
63 }
64 
Quit()65 void MessagePumpDefault::Quit() {
66   keep_running_ = false;
67 }
68 
ScheduleWork()69 void MessagePumpDefault::ScheduleWork() {
70   // Since this can be called on any thread, we need to ensure that our Run
71   // loop wakes up.
72   event_.Signal();
73 }
74 
ScheduleDelayedWork(const Delegate::NextWorkInfo & next_work_info)75 void MessagePumpDefault::ScheduleDelayedWork(
76     const Delegate::NextWorkInfo& next_work_info) {
77   // Since this is always called from the same thread as Run(), there is nothing
78   // to do as the loop is already running. It will wait in Run() with the
79   // correct timeout when it's out of immediate tasks.
80   // TODO(gab): Consider removing ScheduleDelayedWork() when all pumps function
81   // this way (bit.ly/merge-message-pump-do-work).
82 }
83 
84 }  // namespace base
85