current_thread.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // Copyright 2018 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. #ifndef BASE_TASK_CURRENT_THREAD_H_
  5. #define BASE_TASK_CURRENT_THREAD_H_
  6. #include <ostream>
  7. #include "base/base_export.h"
  8. #include "base/callback_forward.h"
  9. #include "base/check.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/scoped_refptr.h"
  12. #include "base/message_loop/message_pump_for_io.h"
  13. #include "base/message_loop/message_pump_for_ui.h"
  14. #include "base/pending_task.h"
  15. #include "base/task/sequence_manager/task_time_observer.h"
  16. #include "base/task/single_thread_task_runner.h"
  17. #include "base/task/task_observer.h"
  18. #include "build/build_config.h"
  19. namespace web {
  20. class WebTaskEnvironment;
  21. }
  22. namespace base {
  23. namespace sequence_manager {
  24. namespace internal {
  25. class SequenceManagerImpl;
  26. }
  27. } // namespace sequence_manager
  28. // CurrentThread is a proxy to a subset of Task related APIs bound to the
  29. // current thread
  30. //
  31. // Current(UI|IO)Thread is available statically through
  32. // Current(UI|IO)Thread::Get() on threads that have registered as CurrentThread
  33. // on this physical thread (e.g. by using SingleThreadTaskExecutor). APIs
  34. // intended for all consumers on the thread should be on Current(UI|IO)Thread,
  35. // while internal APIs might be on multiple internal classes (e.g.
  36. // SequenceManager).
  37. //
  38. // Why: Historically MessageLoop would take care of everything related to event
  39. // processing on a given thread. Nowadays that functionality is split among
  40. // different classes. At that time MessageLoop::current() gave access to the
  41. // full MessageLoop API, preventing both addition of powerful owner-only APIs as
  42. // well as making it harder to remove callers of deprecated APIs (that need to
  43. // stick around for a few owner-only use cases and re-accrue callers after
  44. // cleanup per remaining publicly available).
  45. //
  46. // As such, many methods below are flagged as deprecated and should be removed
  47. // once all static callers have been migrated.
  48. class BASE_EXPORT CurrentThread {
  49. public:
  50. // CurrentThread is effectively just a disguised pointer and is fine to
  51. // copy/move around.
  52. CurrentThread(const CurrentThread& other) = default;
  53. CurrentThread(CurrentThread&& other) = default;
  54. CurrentThread& operator=(const CurrentThread& other) = default;
  55. bool operator==(const CurrentThread& other) const;
  56. // Returns a proxy object to interact with the Task related APIs for the
  57. // current thread. It must only be used on the thread it was obtained.
  58. static CurrentThread Get();
  59. // Return an empty CurrentThread. No methods should be called on this
  60. // object.
  61. static CurrentThread GetNull();
  62. // Returns true if the current thread is registered to expose CurrentThread
  63. // API. Prefer this to verifying the boolean value of Get() (so that Get() can
  64. // ultimately DCHECK it's only invoked when IsSet()).
  65. static bool IsSet();
  66. // Allow CurrentThread to be used like a pointer to support the many
  67. // callsites that used MessageLoop::current() that way when it was a
  68. // MessageLoop*.
  69. CurrentThread* operator->() { return this; }
  70. explicit operator bool() const { return !!current_; }
  71. // A DestructionObserver is notified when the current task execution
  72. // environment is being destroyed. These observers are notified prior to
  73. // CurrentThread::IsSet() being changed to return false. This gives interested
  74. // parties the chance to do final cleanup.
  75. //
  76. // NOTE: Any tasks posted to the current thread during this notification will
  77. // not be run. Instead, they will be deleted.
  78. //
  79. // Deprecation note: Prefer SequenceLocalStorageSlot<std::unique_ptr<Foo>> to
  80. // DestructionObserver to bind an object's lifetime to the current
  81. // thread/sequence.
  82. class BASE_EXPORT DestructionObserver {
  83. public:
  84. // TODO(https://crbug.com/891670): Rename to
  85. // WillDestroyCurrentTaskExecutionEnvironment
  86. virtual void WillDestroyCurrentMessageLoop() = 0;
  87. protected:
  88. virtual ~DestructionObserver() = default;
  89. };
  90. // Add a DestructionObserver, which will start receiving notifications
  91. // immediately.
  92. void AddDestructionObserver(DestructionObserver* destruction_observer);
  93. // Remove a DestructionObserver. It is safe to call this method while a
  94. // DestructionObserver is receiving a notification callback.
  95. void RemoveDestructionObserver(DestructionObserver* destruction_observer);
  96. // Forwards to SequenceManager::SetTaskRunner().
  97. // DEPRECATED(https://crbug.com/825327): only owners of the SequenceManager
  98. // instance should replace its TaskRunner.
  99. void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner);
  100. // Forwards to SequenceManager::(Add|Remove)TaskObserver.
  101. // DEPRECATED(https://crbug.com/825327): only owners of the SequenceManager
  102. // instance should add task observers on it.
  103. void AddTaskObserver(TaskObserver* task_observer);
  104. void RemoveTaskObserver(TaskObserver* task_observer);
  105. // When this functionality is enabled, the queue time will be recorded for
  106. // posted tasks.
  107. void SetAddQueueTimeToTasks(bool enable);
  108. // Registers a OnceClosure to be called on this thread the next time it goes
  109. // idle. This is meant for internal usage; callers should use BEST_EFFORT
  110. // tasks instead of this for generic work that needs to wait until quiescence
  111. // to run. There can only be one OnNextIdleCallback at a time. Can be called
  112. // with a null callback to clear any potentially pending callbacks.
  113. void RegisterOnNextIdleCallback(OnceClosure on_next_idle_callback);
  114. // Enables nested task processing in scope of an upcoming native message loop.
  115. // Some unwanted message loops may occur when using common controls or printer
  116. // functions. Hence, nested task processing is disabled by default to avoid
  117. // unplanned reentrancy. This re-enables it in cases where the stack is
  118. // reentrancy safe and processing nestable tasks is explicitly safe.
  119. //
  120. // For instance,
  121. // - The current thread is running a message loop.
  122. // - It receives a task #1 and executes it.
  123. // - The task #1 implicitly starts a nested message loop, like a MessageBox in
  124. // the unit test. This can also be StartDoc or GetSaveFileName.
  125. // - The thread receives a task #2 before or while in this second message
  126. // loop.
  127. // - With NestableTasksAllowed set to true, the task #2 will run right away.
  128. // Otherwise, it will get executed right after task #1 completes at "thread
  129. // message loop level".
  130. //
  131. // Use RunLoop::Type::kNestableTasksAllowed when nesting is triggered by the
  132. // application RunLoop rather than by native code.
  133. class BASE_EXPORT ScopedAllowApplicationTasksInNativeNestedLoop {
  134. public:
  135. ScopedAllowApplicationTasksInNativeNestedLoop();
  136. ~ScopedAllowApplicationTasksInNativeNestedLoop();
  137. private:
  138. const raw_ptr<sequence_manager::internal::SequenceManagerImpl>
  139. sequence_manager_;
  140. const bool previous_state_;
  141. };
  142. // TODO(https://crbug.com/781352): Remove usage of this old class. Either
  143. // renaming it to ScopedAllowApplicationTasksInNativeNestedLoop when truly
  144. // native or migrating it to RunLoop::Type::kNestableTasksAllowed otherwise.
  145. using ScopedNestableTaskAllower =
  146. ScopedAllowApplicationTasksInNativeNestedLoop;
  147. // Returns true if nestable tasks are allowed on the current thread at this
  148. // time (i.e. if a nested loop would start from the callee's point in the
  149. // stack, would it be allowed to run application tasks).
  150. bool NestableTasksAllowed() const;
  151. // Returns true if this instance is bound to the current thread.
  152. bool IsBoundToCurrentThread() const;
  153. // Returns true if the current thread is idle (ignoring delayed tasks). This
  154. // is the same condition which triggers DoWork() to return false: i.e. out of
  155. // tasks which can be processed at the current run-level -- there might be
  156. // deferred non-nestable tasks remaining if currently in a nested run level.
  157. bool IsIdleForTesting();
  158. // Enables ThreadControllerWithMessagePumpImpl's TimeKeeper metrics.
  159. // `thread_name` will be used as a suffix.
  160. void EnableMessagePumpTimeKeeperMetrics(const char* thread_name);
  161. protected:
  162. explicit CurrentThread(
  163. sequence_manager::internal::SequenceManagerImpl* sequence_manager)
  164. : current_(sequence_manager) {}
  165. static sequence_manager::internal::SequenceManagerImpl*
  166. GetCurrentSequenceManagerImpl();
  167. friend class MessagePumpLibeventTest;
  168. friend class ScheduleWorkTest;
  169. friend class Thread;
  170. friend class sequence_manager::internal::SequenceManagerImpl;
  171. friend class MessageLoopTaskRunnerTest;
  172. friend class web::WebTaskEnvironment;
  173. raw_ptr<sequence_manager::internal::SequenceManagerImpl> current_;
  174. };
  175. #if !BUILDFLAG(IS_NACL)
  176. // UI extension of CurrentThread.
  177. class BASE_EXPORT CurrentUIThread : public CurrentThread {
  178. public:
  179. // Returns an interface for the CurrentUIThread of the current thread.
  180. // Asserts that IsSet().
  181. static CurrentUIThread Get();
  182. // Returns true if the current thread is running a CurrentUIThread.
  183. static bool IsSet();
  184. CurrentUIThread* operator->() { return this; }
  185. #if defined(USE_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN)
  186. static_assert(
  187. std::is_base_of<WatchableIOMessagePumpPosix, MessagePumpForUI>::value,
  188. "CurrentThreadForUI::WatchFileDescriptor is supported only"
  189. "by MessagePumpLibevent and MessagePumpGlib implementations.");
  190. bool WatchFileDescriptor(int fd,
  191. bool persistent,
  192. MessagePumpForUI::Mode mode,
  193. MessagePumpForUI::FdWatchController* controller,
  194. MessagePumpForUI::FdWatcher* delegate);
  195. #endif
  196. #if BUILDFLAG(IS_IOS)
  197. // Forwards to SequenceManager::Attach().
  198. // TODO(https://crbug.com/825327): Plumb the actual SequenceManager* to
  199. // callers and remove ability to access this method from
  200. // CurrentUIThread.
  201. void Attach();
  202. #endif
  203. #if BUILDFLAG(IS_ANDROID)
  204. // Forwards to MessagePumpForUI::Abort().
  205. // TODO(https://crbug.com/825327): Plumb the actual MessagePumpForUI* to
  206. // callers and remove ability to access this method from
  207. // CurrentUIThread.
  208. void Abort();
  209. #endif
  210. #if BUILDFLAG(IS_WIN)
  211. void AddMessagePumpObserver(MessagePumpForUI::Observer* observer);
  212. void RemoveMessagePumpObserver(MessagePumpForUI::Observer* observer);
  213. #endif
  214. private:
  215. explicit CurrentUIThread(
  216. sequence_manager::internal::SequenceManagerImpl* current)
  217. : CurrentThread(current) {}
  218. MessagePumpForUI* GetMessagePumpForUI() const;
  219. };
  220. #endif // !BUILDFLAG(IS_NACL)
  221. // ForIO extension of CurrentThread.
  222. class BASE_EXPORT CurrentIOThread : public CurrentThread {
  223. public:
  224. // Returns an interface for the CurrentIOThread of the current thread.
  225. // Asserts that IsSet().
  226. static CurrentIOThread Get();
  227. // Returns true if the current thread is running a CurrentIOThread.
  228. static bool IsSet();
  229. CurrentIOThread* operator->() { return this; }
  230. #if !BUILDFLAG(IS_NACL)
  231. #if BUILDFLAG(IS_WIN)
  232. // Please see MessagePumpWin for definitions of these methods.
  233. HRESULT RegisterIOHandler(HANDLE file, MessagePumpForIO::IOHandler* handler);
  234. bool RegisterJobObject(HANDLE job, MessagePumpForIO::IOHandler* handler);
  235. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  236. // Please see WatchableIOMessagePumpPosix for definition.
  237. // Prefer base::FileDescriptorWatcher for non-critical IO.
  238. bool WatchFileDescriptor(int fd,
  239. bool persistent,
  240. MessagePumpForIO::Mode mode,
  241. MessagePumpForIO::FdWatchController* controller,
  242. MessagePumpForIO::FdWatcher* delegate);
  243. #endif // BUILDFLAG(IS_WIN)
  244. #if BUILDFLAG(IS_MAC)
  245. bool WatchMachReceivePort(
  246. mach_port_t port,
  247. MessagePumpForIO::MachPortWatchController* controller,
  248. MessagePumpForIO::MachPortWatcher* delegate);
  249. #endif
  250. #if BUILDFLAG(IS_FUCHSIA)
  251. // Additional watch API for native platform resources.
  252. bool WatchZxHandle(zx_handle_t handle,
  253. bool persistent,
  254. zx_signals_t signals,
  255. MessagePumpForIO::ZxHandleWatchController* controller,
  256. MessagePumpForIO::ZxHandleWatcher* delegate);
  257. #endif // BUILDFLAG(IS_FUCHSIA)
  258. #endif // !BUILDFLAG(IS_NACL)
  259. private:
  260. explicit CurrentIOThread(
  261. sequence_manager::internal::SequenceManagerImpl* current)
  262. : CurrentThread(current) {}
  263. MessagePumpForIO* GetMessagePumpForIO() const;
  264. };
  265. } // namespace base
  266. #endif // BASE_TASK_CURRENT_THREAD_H_