post_task.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright 2016 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_POST_TASK_H_
  5. #define BASE_TASK_POST_TASK_H_
  6. #include <memory>
  7. #include <utility>
  8. #include "base/base_export.h"
  9. #include "base/bind.h"
  10. #include "base/callback.h"
  11. #include "base/callback_helpers.h"
  12. #include "base/location.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/post_task_and_reply_with_result_internal.h"
  15. #include "base/sequenced_task_runner.h"
  16. #include "base/single_thread_task_runner.h"
  17. #include "base/task/single_thread_task_runner_thread_mode.h"
  18. #include "base/task/task_traits.h"
  19. #include "base/task_runner.h"
  20. #include "base/time/time.h"
  21. #include "base/updateable_sequenced_task_runner.h"
  22. #include "build/build_config.h"
  23. namespace base {
  24. // This is the interface to post tasks.
  25. //
  26. // Note: A migration is in-progress away from this API and in favor of explicit
  27. // API-as-a-destination. thread_pool.h is now preferred to the
  28. // base::ThreadPool() to post to the thread pool
  29. //
  30. // To post a simple one-off task with default traits:
  31. // PostTask(FROM_HERE, BindOnce(...));
  32. // modern equivalent:
  33. // ThreadPool::PostTask(FROM_HERE, BindOnce(...));
  34. //
  35. // To post a high priority one-off task to respond to a user interaction:
  36. // PostTask(
  37. // FROM_HERE,
  38. // {ThreadPool(), TaskPriority::USER_BLOCKING},
  39. // BindOnce(...));
  40. // modern equivalent:
  41. // ThreadPool::PostTask(
  42. // FROM_HERE,
  43. // {TaskPriority::USER_BLOCKING},
  44. // BindOnce(...));
  45. //
  46. // To post tasks that must run in sequence with default traits:
  47. // scoped_refptr<SequencedTaskRunner> task_runner =
  48. // CreateSequencedTaskRunner({ThreadPool()});
  49. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  50. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  51. // modern equivalent:
  52. // scoped_refptr<SequencedTaskRunner> task_runner =
  53. // ThreadPool::CreateSequencedTaskRunner({});
  54. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  55. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  56. //
  57. // To post tasks that may block, must run in sequence and can be skipped on
  58. // shutdown:
  59. // scoped_refptr<SequencedTaskRunner> task_runner =
  60. // CreateSequencedTaskRunner({ThreadPool(), MayBlock(),
  61. // TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
  62. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  63. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  64. // modern equivalent:
  65. // scoped_refptr<SequencedTaskRunner> task_runner =
  66. // ThreadPool::CreateSequencedTaskRunner(
  67. // {MayBlock(), TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
  68. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  69. // task_runner->PostTask(FROM_HERE, BindOnce(...));
  70. //
  71. // The default traits apply to tasks that:
  72. // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()),
  73. // (2) prefer inheriting the current priority to specifying their own, and
  74. // (3) can either block shutdown or be skipped on shutdown
  75. // (implementation is free to choose a fitting default).
  76. // Explicit traits must be specified for tasks for which these loose
  77. // requirements are not sufficient.
  78. //
  79. // Tasks posted with only traits defined in base/task/task_traits.h run on
  80. // threads owned by the registered ThreadPoolInstance (i.e. not on the main
  81. // thread). An embedder (e.g. Chrome) can define additional traits to make tasks
  82. // run on threads of their choosing.
  83. //
  84. // Tasks posted with the same traits will be scheduled in the order they were
  85. // posted. IMPORTANT: Please note however that, unless the traits imply a
  86. // single thread or sequence, this doesn't guarantee any *execution ordering*
  87. // for tasks posted in a given order (being scheduled first doesn't mean it will
  88. // run first -- could run in parallel or have its physical thread preempted).
  89. //
  90. // Prerequisite: A ThreadPoolInstance must have been registered for the current
  91. // process via ThreadPoolInstance::Set() before the functions below are
  92. // valid. This is typically done during the initialization phase in each
  93. // process. If your code is not running in that phase, you most likely don't
  94. // have to worry about this. You will encounter DCHECKs or nullptr dereferences
  95. // if this is violated. For tests, prefer base::test::TaskEnvironment.
  96. // Posts |task| with specific |traits|. Returns false if the task definitely
  97. // won't run because of current shutdown state.
  98. BASE_EXPORT bool PostTask(const Location& from_here,
  99. const TaskTraits& traits,
  100. OnceClosure task);
  101. // Posts |task| with specific |traits|. |task| will not run before |delay|
  102. // expires. Returns false if the task definitely won't run because of current
  103. // shutdown state.
  104. //
  105. // Specify a BEST_EFFORT priority via |traits| if the task doesn't have to run
  106. // as soon as |delay| expires.
  107. BASE_EXPORT bool PostDelayedTask(const Location& from_here,
  108. const TaskTraits& traits,
  109. OnceClosure task,
  110. TimeDelta delay);
  111. // Posts |task| with specific |traits| and posts |reply| on the caller's
  112. // execution context (i.e. same sequence or thread and same TaskTraits if
  113. // applicable) when |task| completes. Returns false if the task definitely won't
  114. // run because of current shutdown state. Can only be called when
  115. // SequencedTaskRunnerHandle::IsSet().
  116. BASE_EXPORT bool PostTaskAndReply(const Location& from_here,
  117. const TaskTraits& traits,
  118. OnceClosure task,
  119. OnceClosure reply);
  120. // Posts |task| with specific |traits| and posts |reply| with the return value
  121. // of |task| as argument on the caller's execution context (i.e. same sequence
  122. // or thread and same TaskTraits if applicable) when |task| completes. Returns
  123. // false if the task definitely won't run because of current shutdown state. Can
  124. // only be called when SequencedTaskRunnerHandle::IsSet().
  125. template <typename TaskReturnType, typename ReplyArgType>
  126. bool PostTaskAndReplyWithResult(const Location& from_here,
  127. const TaskTraits& traits,
  128. OnceCallback<TaskReturnType()> task,
  129. OnceCallback<void(ReplyArgType)> reply) {
  130. auto* result = new std::unique_ptr<TaskReturnType>();
  131. return PostTaskAndReply(
  132. from_here, traits,
  133. BindOnce(&internal::ReturnAsParamAdapter<TaskReturnType>, std::move(task),
  134. result),
  135. BindOnce(&internal::ReplyAdapter<TaskReturnType, ReplyArgType>,
  136. std::move(reply), Owned(result)));
  137. }
  138. // Returns a TaskRunner whose PostTask invocations result in scheduling tasks
  139. // using |traits|. Tasks may run in any order and in parallel.
  140. BASE_EXPORT scoped_refptr<TaskRunner> CreateTaskRunner(
  141. const TaskTraits& traits);
  142. // Returns a SequencedTaskRunner whose PostTask invocations result in scheduling
  143. // tasks using |traits|. Tasks run one at a time in posting order.
  144. BASE_EXPORT scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunner(
  145. const TaskTraits& traits);
  146. // Returns a task runner whose PostTask invocations result in scheduling tasks
  147. // using |traits|. The priority in |traits| can be updated at any time via
  148. // UpdateableSequencedTaskRunner::UpdatePriority(). An update affects all tasks
  149. // posted to the task runner that aren't running yet. Tasks run one at a time in
  150. // posting order.
  151. //
  152. // |traits| requirements:
  153. // - base::ThreadPool() must be specified.
  154. // Note: Prefer the explicit (thread_pool.h) version of this API while we
  155. // migrate this one to it.
  156. // - Extension traits (e.g. BrowserThread) cannot be specified.
  157. // - base::ThreadPolicy must be specified if the priority of the task runner
  158. // will ever be increased from BEST_EFFORT.
  159. BASE_EXPORT scoped_refptr<UpdateableSequencedTaskRunner>
  160. CreateUpdateableSequencedTaskRunner(const TaskTraits& traits);
  161. // Returns a SingleThreadTaskRunner whose PostTask invocations result in
  162. // scheduling tasks using |traits| on a thread determined by |thread_mode|. See
  163. // base/task/single_thread_task_runner_thread_mode.h for |thread_mode| details.
  164. // If |traits| identifies an existing thread,
  165. // SingleThreadTaskRunnerThreadMode::SHARED must be used. Tasks run on a single
  166. // thread in posting order.
  167. //
  168. // If all you need is to make sure that tasks don't run concurrently (e.g.
  169. // because they access a data structure which is not thread-safe), use
  170. // CreateSequencedTaskRunner(). Only use this if you rely on a thread-affine API
  171. // (it might be safer to assume thread-affinity when dealing with
  172. // under-documented third-party APIs, e.g. other OS') or share data across tasks
  173. // using thread-local storage.
  174. BASE_EXPORT scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner(
  175. const TaskTraits& traits,
  176. SingleThreadTaskRunnerThreadMode thread_mode =
  177. SingleThreadTaskRunnerThreadMode::SHARED);
  178. #if defined(OS_WIN)
  179. // Returns a SingleThreadTaskRunner whose PostTask invocations result in
  180. // scheduling tasks using |traits| in a COM Single-Threaded Apartment on a
  181. // thread determined by |thread_mode|. See
  182. // base/task/single_thread_task_runner_thread_mode.h for |thread_mode| details.
  183. // If |traits| identifies an existing thread,
  184. // SingleThreadTaskRunnerThreadMode::SHARED must be used. Tasks run in the same
  185. // Single-Threaded Apartment in posting order for the returned
  186. // SingleThreadTaskRunner. There is not necessarily a one-to-one correspondence
  187. // between SingleThreadTaskRunners and Single-Threaded Apartments. The
  188. // implementation is free to share apartments or create new apartments as
  189. // necessary. In either case, care should be taken to make sure COM pointers are
  190. // not smuggled across apartments.
  191. BASE_EXPORT scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner(
  192. const TaskTraits& traits,
  193. SingleThreadTaskRunnerThreadMode thread_mode =
  194. SingleThreadTaskRunnerThreadMode::SHARED);
  195. #endif // defined(OS_WIN)
  196. // Helpers to send a Delete/ReleaseSoon to a new SequencedTaskRunner created
  197. // from |traits|. The semantics match base::PostTask in that the deletion is
  198. // guaranteed to be scheduled in order with other tasks using the same |traits|.
  199. //
  200. // Prefer using an existing SequencedTaskRunner's Delete/ReleaseSoon over this
  201. // to encode execution order requirements when possible.
  202. //
  203. // Note: base::ThreadPool is not a valid destination as it'd result in a one-off
  204. // parallel task which is generally ill-suited for deletion. Use an existing
  205. // SequencedTaskRunner's DeleteSoon to post a safely ordered deletion.
  206. template <class T>
  207. bool DeleteSoon(const Location& from_here,
  208. const TaskTraits& traits,
  209. const T* object) {
  210. DCHECK(!traits.use_thread_pool());
  211. return CreateSequencedTaskRunner(traits)->DeleteSoon(from_here, object);
  212. }
  213. template <class T>
  214. bool DeleteSoon(const Location& from_here,
  215. const TaskTraits& traits,
  216. std::unique_ptr<T> object) {
  217. return DeleteSoon(from_here, traits, object.release());
  218. }
  219. template <class T>
  220. void ReleaseSoon(const Location& from_here,
  221. const TaskTraits& traits,
  222. scoped_refptr<T>&& object) {
  223. DCHECK(!traits.use_thread_pool());
  224. CreateSequencedTaskRunner(traits)->ReleaseSoon(from_here, std::move(object));
  225. }
  226. } // namespace base
  227. #endif // BASE_TASK_POST_TASK_H_