xref: /aosp_15_r20/external/cronet/base/task/current_thread.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 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/task/current_thread.h"
6 
7 #include <utility>
8 
9 #include "base/callback_list.h"
10 #include "base/functional/bind.h"
11 #include "base/functional/callback.h"
12 #include "base/message_loop/message_pump_for_io.h"
13 #include "base/message_loop/message_pump_for_ui.h"
14 #include "base/message_loop/message_pump_type.h"
15 #include "base/task/sequence_manager/sequence_manager_impl.h"
16 #include "base/threading/thread_local.h"
17 #include "base/trace_event/base_tracing.h"
18 #include "build/build_config.h"
19 
20 namespace base {
21 
22 //------------------------------------------------------------------------------
23 // CurrentThread
24 
25 // static
26 sequence_manager::internal::SequenceManagerImpl*
GetCurrentSequenceManagerImpl()27 CurrentThread::GetCurrentSequenceManagerImpl() {
28   return sequence_manager::internal::SequenceManagerImpl::GetCurrent();
29 }
30 
31 // static
Get()32 CurrentThread CurrentThread::Get() {
33   return CurrentThread(GetCurrentSequenceManagerImpl());
34 }
35 
36 // static
GetNull()37 CurrentThread CurrentThread::GetNull() {
38   return CurrentThread(nullptr);
39 }
40 
41 // static
IsSet()42 bool CurrentThread::IsSet() {
43   return !!GetCurrentSequenceManagerImpl();
44 }
45 
AddDestructionObserver(DestructionObserver * destruction_observer)46 void CurrentThread::AddDestructionObserver(
47     DestructionObserver* destruction_observer) {
48   DCHECK(current_->IsBoundToCurrentThread());
49   current_->AddDestructionObserver(destruction_observer);
50 }
51 
RemoveDestructionObserver(DestructionObserver * destruction_observer)52 void CurrentThread::RemoveDestructionObserver(
53     DestructionObserver* destruction_observer) {
54   DCHECK(current_->IsBoundToCurrentThread());
55   current_->RemoveDestructionObserver(destruction_observer);
56 }
57 
SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner)58 void CurrentThread::SetTaskRunner(
59     scoped_refptr<SingleThreadTaskRunner> task_runner) {
60   DCHECK(current_->IsBoundToCurrentThread());
61   current_->SetTaskRunner(std::move(task_runner));
62 }
63 
IsBoundToCurrentThread() const64 bool CurrentThread::IsBoundToCurrentThread() const {
65   return current_ == GetCurrentSequenceManagerImpl();
66 }
67 
IsIdleForTesting()68 bool CurrentThread::IsIdleForTesting() {
69   DCHECK(current_->IsBoundToCurrentThread());
70   return current_->IsIdleForTesting();
71 }
72 
EnableMessagePumpTimeKeeperMetrics(const char * thread_name)73 void CurrentThread::EnableMessagePumpTimeKeeperMetrics(
74     const char* thread_name) {
75   return current_->EnableMessagePumpTimeKeeperMetrics(thread_name);
76 }
77 
AddTaskObserver(TaskObserver * task_observer)78 void CurrentThread::AddTaskObserver(TaskObserver* task_observer) {
79   DCHECK(current_->IsBoundToCurrentThread());
80   current_->AddTaskObserver(task_observer);
81 }
82 
RemoveTaskObserver(TaskObserver * task_observer)83 void CurrentThread::RemoveTaskObserver(TaskObserver* task_observer) {
84   DCHECK(current_->IsBoundToCurrentThread());
85   current_->RemoveTaskObserver(task_observer);
86 }
87 
SetAddQueueTimeToTasks(bool enable)88 void CurrentThread::SetAddQueueTimeToTasks(bool enable) {
89   DCHECK(current_->IsBoundToCurrentThread());
90   current_->SetAddQueueTimeToTasks(enable);
91 }
92 
RegisterOnNextIdleCallback(RegisterOnNextIdleCallbackPasskey,OnceClosure on_next_idle_callback)93 CallbackListSubscription CurrentThread::RegisterOnNextIdleCallback(
94     RegisterOnNextIdleCallbackPasskey,
95     OnceClosure on_next_idle_callback) {
96   return current_->RegisterOnNextIdleCallback(std::move(on_next_idle_callback));
97 }
98 
99 CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop::
ScopedAllowApplicationTasksInNativeNestedLoop()100     ScopedAllowApplicationTasksInNativeNestedLoop()
101     : sequence_manager_(GetCurrentSequenceManagerImpl()),
102       previous_state_(
103           sequence_manager_->IsTaskExecutionAllowedInNativeNestedLoop()) {
104   TRACE_EVENT_BEGIN0("base", "ScopedNestableTaskAllower");
105   sequence_manager_->SetTaskExecutionAllowedInNativeNestedLoop(true);
106 }
107 
108 CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop::
~ScopedAllowApplicationTasksInNativeNestedLoop()109     ~ScopedAllowApplicationTasksInNativeNestedLoop() {
110   sequence_manager_->SetTaskExecutionAllowedInNativeNestedLoop(previous_state_);
111   TRACE_EVENT_END0("base", "ScopedNestableTaskAllower");
112 }
113 
ApplicationTasksAllowedInNativeNestedLoop() const114 bool CurrentThread::ApplicationTasksAllowedInNativeNestedLoop() const {
115   return current_->IsTaskExecutionAllowedInNativeNestedLoop();
116 }
117 
118 #if !BUILDFLAG(IS_NACL)
119 
120 //------------------------------------------------------------------------------
121 // CurrentUIThread
122 
123 // static
Get()124 CurrentUIThread CurrentUIThread::Get() {
125   auto* sequence_manager = GetCurrentSequenceManagerImpl();
126   DCHECK(sequence_manager);
127 #if BUILDFLAG(IS_ANDROID)
128   DCHECK(sequence_manager->IsType(MessagePumpType::UI) ||
129          sequence_manager->IsType(MessagePumpType::JAVA));
130 #else   // BUILDFLAG(IS_ANDROID)
131   DCHECK(sequence_manager->IsType(MessagePumpType::UI));
132 #endif  // BUILDFLAG(IS_ANDROID)
133   return CurrentUIThread(sequence_manager);
134 }
135 
136 // static
IsSet()137 bool CurrentUIThread::IsSet() {
138   sequence_manager::internal::SequenceManagerImpl* sequence_manager =
139       GetCurrentSequenceManagerImpl();
140   return sequence_manager &&
141 #if BUILDFLAG(IS_ANDROID)
142          (sequence_manager->IsType(MessagePumpType::UI) ||
143           sequence_manager->IsType(MessagePumpType::JAVA));
144 #else   // BUILDFLAG(IS_ANDROID)
145          sequence_manager->IsType(MessagePumpType::UI);
146 #endif  // BUILDFLAG(IS_ANDROID)
147 }
148 
GetMessagePumpForUI() const149 MessagePumpForUI* CurrentUIThread::GetMessagePumpForUI() const {
150   return static_cast<MessagePumpForUI*>(current_->GetMessagePump());
151 }
152 
153 #if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN)
WatchFileDescriptor(int fd,bool persistent,MessagePumpForUI::Mode mode,MessagePumpForUI::FdWatchController * controller,MessagePumpForUI::FdWatcher * delegate)154 bool CurrentUIThread::WatchFileDescriptor(
155     int fd,
156     bool persistent,
157     MessagePumpForUI::Mode mode,
158     MessagePumpForUI::FdWatchController* controller,
159     MessagePumpForUI::FdWatcher* delegate) {
160   DCHECK(current_->IsBoundToCurrentThread());
161   return GetMessagePumpForUI()->WatchFileDescriptor(fd, persistent, mode,
162                                                     controller, delegate);
163 }
164 #endif
165 
166 #if BUILDFLAG(IS_IOS)
Attach()167 void CurrentUIThread::Attach() {
168   current_->AttachToMessagePump();
169 }
170 #endif  // BUILDFLAG(IS_IOS)
171 
172 #if BUILDFLAG(IS_ANDROID)
Abort()173 void CurrentUIThread::Abort() {
174   GetMessagePumpForUI()->Abort();
175 }
176 #endif  // BUILDFLAG(IS_ANDROID)
177 
178 #if BUILDFLAG(IS_WIN)
AddMessagePumpObserver(MessagePumpForUI::Observer * observer)179 void CurrentUIThread::AddMessagePumpObserver(
180     MessagePumpForUI::Observer* observer) {
181   GetMessagePumpForUI()->AddObserver(observer);
182 }
183 
RemoveMessagePumpObserver(MessagePumpForUI::Observer * observer)184 void CurrentUIThread::RemoveMessagePumpObserver(
185     MessagePumpForUI::Observer* observer) {
186   GetMessagePumpForUI()->RemoveObserver(observer);
187 }
188 #endif  // BUILDFLAG(IS_WIN)
189 
190 #endif  // !BUILDFLAG(IS_NACL)
191 
192 //------------------------------------------------------------------------------
193 // CurrentIOThread
194 
195 // static
Get()196 CurrentIOThread CurrentIOThread::Get() {
197   auto* sequence_manager = GetCurrentSequenceManagerImpl();
198   DCHECK(sequence_manager);
199   DCHECK(sequence_manager->IsType(MessagePumpType::IO));
200   return CurrentIOThread(sequence_manager);
201 }
202 
203 // static
IsSet()204 bool CurrentIOThread::IsSet() {
205   auto* sequence_manager = GetCurrentSequenceManagerImpl();
206   return sequence_manager && sequence_manager->IsType(MessagePumpType::IO);
207 }
208 
GetMessagePumpForIO() const209 MessagePumpForIO* CurrentIOThread::GetMessagePumpForIO() const {
210   return static_cast<MessagePumpForIO*>(current_->GetMessagePump());
211 }
212 
213 #if !BUILDFLAG(IS_NACL)
214 
215 #if BUILDFLAG(IS_WIN)
RegisterIOHandler(HANDLE file,MessagePumpForIO::IOHandler * handler)216 HRESULT CurrentIOThread::RegisterIOHandler(
217     HANDLE file,
218     MessagePumpForIO::IOHandler* handler) {
219   DCHECK(current_->IsBoundToCurrentThread());
220   return GetMessagePumpForIO()->RegisterIOHandler(file, handler);
221 }
222 
RegisterJobObject(HANDLE job,MessagePumpForIO::IOHandler * handler)223 bool CurrentIOThread::RegisterJobObject(HANDLE job,
224                                         MessagePumpForIO::IOHandler* handler) {
225   DCHECK(current_->IsBoundToCurrentThread());
226   return GetMessagePumpForIO()->RegisterJobObject(job, handler);
227 }
228 
229 #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
WatchFileDescriptor(int fd,bool persistent,MessagePumpForIO::Mode mode,MessagePumpForIO::FdWatchController * controller,MessagePumpForIO::FdWatcher * delegate)230 bool CurrentIOThread::WatchFileDescriptor(
231     int fd,
232     bool persistent,
233     MessagePumpForIO::Mode mode,
234     MessagePumpForIO::FdWatchController* controller,
235     MessagePumpForIO::FdWatcher* delegate) {
236   DCHECK(current_->IsBoundToCurrentThread());
237   return GetMessagePumpForIO()->WatchFileDescriptor(fd, persistent, mode,
238                                                     controller, delegate);
239 }
240 #endif  // BUILDFLAG(IS_WIN)
241 
242 #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD))
WatchMachReceivePort(mach_port_t port,MessagePumpForIO::MachPortWatchController * controller,MessagePumpForIO::MachPortWatcher * delegate)243 bool CurrentIOThread::WatchMachReceivePort(
244     mach_port_t port,
245     MessagePumpForIO::MachPortWatchController* controller,
246     MessagePumpForIO::MachPortWatcher* delegate) {
247   DCHECK(current_->IsBoundToCurrentThread());
248   return GetMessagePumpForIO()->WatchMachReceivePort(port, controller,
249                                                      delegate);
250 }
251 #endif
252 
253 #endif  // !BUILDFLAG(IS_NACL)
254 
255 #if BUILDFLAG(IS_FUCHSIA)
256 // Additional watch API for native platform resources.
WatchZxHandle(zx_handle_t handle,bool persistent,zx_signals_t signals,MessagePumpForIO::ZxHandleWatchController * controller,MessagePumpForIO::ZxHandleWatcher * delegate)257 bool CurrentIOThread::WatchZxHandle(
258     zx_handle_t handle,
259     bool persistent,
260     zx_signals_t signals,
261     MessagePumpForIO::ZxHandleWatchController* controller,
262     MessagePumpForIO::ZxHandleWatcher* delegate) {
263   DCHECK(current_->IsBoundToCurrentThread());
264   return GetMessagePumpForIO()->WatchZxHandle(handle, persistent, signals,
265                                               controller, delegate);
266 }
267 #endif
268 
269 }  // namespace base
270