xref: /aosp_15_r20/external/cronet/base/task/bind_post_task.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TASK_BIND_POST_TASK_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_TASK_BIND_POST_TASK_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <type_traits>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/task/bind_post_task_internal.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/task/task_runner.h"
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker // BindPostTask() is a helper function for binding a OnceCallback or
20*6777b538SAndroid Build Coastguard Worker // RepeatingCallback to a task runner. BindPostTask(task_runner, callback)
21*6777b538SAndroid Build Coastguard Worker // returns a task runner bound callback with an identical type to |callback|.
22*6777b538SAndroid Build Coastguard Worker // The returned callback will take the same arguments as the input |callback|.
23*6777b538SAndroid Build Coastguard Worker // Invoking Run() on the returned callback will post a task to run |callback| on
24*6777b538SAndroid Build Coastguard Worker // target |task_runner| with the provided arguments.
25*6777b538SAndroid Build Coastguard Worker //
26*6777b538SAndroid Build Coastguard Worker // This is typically used when a callback must be invoked on a specific task
27*6777b538SAndroid Build Coastguard Worker // runner but is provided as a result callback to a function that runs
28*6777b538SAndroid Build Coastguard Worker // asynchronously on a different task runner.
29*6777b538SAndroid Build Coastguard Worker //
30*6777b538SAndroid Build Coastguard Worker // Example:
31*6777b538SAndroid Build Coastguard Worker //    // |result_cb| can only be safely run on |my_task_runner|.
32*6777b538SAndroid Build Coastguard Worker //    auto result_cb = BindOnce(&Foo::ReceiveReply, foo);
33*6777b538SAndroid Build Coastguard Worker //    // Note that even if |returned_cb| is never run |result_cb| will attempt
34*6777b538SAndroid Build Coastguard Worker //    // to be destroyed on |my_task_runner|.
35*6777b538SAndroid Build Coastguard Worker //    auto returned_cb = BindPostTask(my_task_runner, std::move(result_cb));
36*6777b538SAndroid Build Coastguard Worker //    // RunAsyncTask() will run the provided callback upon completion.
37*6777b538SAndroid Build Coastguard Worker //    other_task_runner->PostTask(FROM_HERE,
38*6777b538SAndroid Build Coastguard Worker //                                BindOnce(&RunAsyncTask,
39*6777b538SAndroid Build Coastguard Worker //                                         std::move(returned_cb)));
40*6777b538SAndroid Build Coastguard Worker //
41*6777b538SAndroid Build Coastguard Worker // If the example provided |result_cb| to RunAsyncTask() then |result_cb| would
42*6777b538SAndroid Build Coastguard Worker // run unsafely on |other_task_runner|. Instead RunAsyncTask() will run
43*6777b538SAndroid Build Coastguard Worker // |returned_cb| which will post a task to |current_task_runner| before running
44*6777b538SAndroid Build Coastguard Worker // |result_cb| safely.
45*6777b538SAndroid Build Coastguard Worker //
46*6777b538SAndroid Build Coastguard Worker // An alternative approach in the example above is to change RunAsyncTask() to
47*6777b538SAndroid Build Coastguard Worker // also take a task runner as an argument and have RunAsyncTask() post the task.
48*6777b538SAndroid Build Coastguard Worker // For cases where that isn't desirable BindPostTask() provides a convenient
49*6777b538SAndroid Build Coastguard Worker // alternative.
50*6777b538SAndroid Build Coastguard Worker //
51*6777b538SAndroid Build Coastguard Worker // The input |callback| will always attempt to be destroyed on the target task
52*6777b538SAndroid Build Coastguard Worker // runner. Even if the returned callback is never invoked, a task will be posted
53*6777b538SAndroid Build Coastguard Worker // to destroy the input |callback|. However, if the target task runner has
54*6777b538SAndroid Build Coastguard Worker // shutdown this is no longer possible. PostTask() will return false and the
55*6777b538SAndroid Build Coastguard Worker // callback will be destroyed immediately on the current thread.
56*6777b538SAndroid Build Coastguard Worker //
57*6777b538SAndroid Build Coastguard Worker // The input |callback| must have a void return type to be compatible with
58*6777b538SAndroid Build Coastguard Worker // PostTask(). If you want to drop the callback return value then use
59*6777b538SAndroid Build Coastguard Worker // base::IgnoreResult(&Func) when creating the input |callback|.
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker namespace base {
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker // Creates a OnceCallback that will run |callback| on |task_runner|. If the
64*6777b538SAndroid Build Coastguard Worker // returned callback is destroyed without being run then |callback| will be
65*6777b538SAndroid Build Coastguard Worker // be destroyed on |task_runner|.
66*6777b538SAndroid Build Coastguard Worker template <typename ReturnType, typename... Args>
67*6777b538SAndroid Build Coastguard Worker   requires std::is_void_v<ReturnType>
68*6777b538SAndroid Build Coastguard Worker OnceCallback<void(Args...)> BindPostTask(
69*6777b538SAndroid Build Coastguard Worker     scoped_refptr<TaskRunner> task_runner,
70*6777b538SAndroid Build Coastguard Worker     OnceCallback<ReturnType(Args...)> callback,
71*6777b538SAndroid Build Coastguard Worker     const Location& location = FROM_HERE) {
72*6777b538SAndroid Build Coastguard Worker   using Helper = internal::BindPostTaskTrampoline<OnceCallback<void(Args...)>>;
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   return base::BindOnce(
75*6777b538SAndroid Build Coastguard Worker       &Helper::template Run<Args...>,
76*6777b538SAndroid Build Coastguard Worker       std::make_unique<Helper>(std::move(task_runner), location,
77*6777b538SAndroid Build Coastguard Worker                                std::move(callback)));
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker // Creates a RepeatingCallback that will run |callback| on |task_runner|. When
81*6777b538SAndroid Build Coastguard Worker // the returned callback is destroyed a task will be posted to destroy the input
82*6777b538SAndroid Build Coastguard Worker // |callback| on |task_runner|.
83*6777b538SAndroid Build Coastguard Worker template <typename ReturnType, typename... Args>
84*6777b538SAndroid Build Coastguard Worker   requires std::is_void_v<ReturnType>
85*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(Args...)> BindPostTask(
86*6777b538SAndroid Build Coastguard Worker     scoped_refptr<TaskRunner> task_runner,
87*6777b538SAndroid Build Coastguard Worker     RepeatingCallback<ReturnType(Args...)> callback,
88*6777b538SAndroid Build Coastguard Worker     const Location& location = FROM_HERE) {
89*6777b538SAndroid Build Coastguard Worker   using Helper =
90*6777b538SAndroid Build Coastguard Worker       internal::BindPostTaskTrampoline<RepeatingCallback<void(Args...)>>;
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   return base::BindRepeating(
93*6777b538SAndroid Build Coastguard Worker       &Helper::template Run<Args...>,
94*6777b538SAndroid Build Coastguard Worker       std::make_unique<Helper>(std::move(task_runner), location,
95*6777b538SAndroid Build Coastguard Worker                                std::move(callback)));
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker // Creates a OnceCallback or RepeatingCallback that will run the `callback` on
99*6777b538SAndroid Build Coastguard Worker // the default SequencedTaskRunner for the current sequence, i.e.
100*6777b538SAndroid Build Coastguard Worker // `SequencedTaskRunner::GetCurrentDefault()`.
101*6777b538SAndroid Build Coastguard Worker // Notes:
102*6777b538SAndroid Build Coastguard Worker // - Please prefer using `base::SequenceBound<T>` if applicable.
103*6777b538SAndroid Build Coastguard Worker // - Please consider using `base::PostTaskAndReplyWithResult()` instead where
104*6777b538SAndroid Build Coastguard Worker // appropriate.
105*6777b538SAndroid Build Coastguard Worker // - Please consider using an explicit task runner.
106*6777b538SAndroid Build Coastguard Worker // - Only use this helper as a last resort if none of the above apply.
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker template <typename ReturnType, typename... Args>
109*6777b538SAndroid Build Coastguard Worker   requires std::is_void_v<ReturnType>
110*6777b538SAndroid Build Coastguard Worker OnceCallback<void(Args...)> BindPostTaskToCurrentDefault(
111*6777b538SAndroid Build Coastguard Worker     OnceCallback<ReturnType(Args...)> callback,
112*6777b538SAndroid Build Coastguard Worker     const Location& location = FROM_HERE) {
113*6777b538SAndroid Build Coastguard Worker   return BindPostTask(SequencedTaskRunner::GetCurrentDefault(),
114*6777b538SAndroid Build Coastguard Worker                       std::move(callback), location);
115*6777b538SAndroid Build Coastguard Worker }
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker template <typename ReturnType, typename... Args>
118*6777b538SAndroid Build Coastguard Worker   requires std::is_void_v<ReturnType>
119*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(Args...)> BindPostTaskToCurrentDefault(
120*6777b538SAndroid Build Coastguard Worker     RepeatingCallback<ReturnType(Args...)> callback,
121*6777b538SAndroid Build Coastguard Worker     const Location& location = FROM_HERE) {
122*6777b538SAndroid Build Coastguard Worker   return BindPostTask(SequencedTaskRunner::GetCurrentDefault(),
123*6777b538SAndroid Build Coastguard Worker                       std::move(callback), location);
124*6777b538SAndroid Build Coastguard Worker }
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker }  // namespace base
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker #endif  // BASE_TASK_BIND_POST_TASK_H_
129