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