1 // Copyright (c) 2012 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 5 #ifndef BASE_TASK_RUNNER_UTIL_H_ 6 #define BASE_TASK_RUNNER_UTIL_H_ 7 8 #include "base/bind.h" 9 #include "base/bind_helpers.h" 10 #include "base/callback_internal.h" 11 #include "base/logging.h" 12 #include "base/task_runner.h" 13 14 namespace base { 15 16 namespace internal { 17 18 // Adapts a function that produces a result via a return value to 19 // one that returns via an output parameter. 20 template <typename ReturnType> 21 void ReturnAsParamAdapter(const Callback<ReturnType(void)>& func, 22 ReturnType* result) { 23 *result = func.Run(); 24 } 25 26 // Adapts a T* result to a callblack that expects a T. 27 template <typename TaskReturnType, typename ReplyArgType> 28 void ReplyAdapter(const Callback<void(ReplyArgType)>& callback, 29 TaskReturnType* result) { 30 // TODO(ajwong): Remove this conditional and add a DCHECK to enforce that 31 // |reply| must be non-null in PostTaskAndReplyWithResult() below after 32 // current code that relies on this API softness has been removed. 33 // http://crbug.com/162712 34 if (!callback.is_null()) 35 callback.Run(CallbackForward(*result)); 36 } 37 38 } // namespace internal 39 40 // When you have these methods 41 // 42 // R DoWorkAndReturn(); 43 // void Callback(const R& result); 44 // 45 // and want to call them in a PostTaskAndReply kind of fashion where the 46 // result of DoWorkAndReturn is passed to the Callback, you can use 47 // PostTaskAndReplyWithResult as in this example: 48 // 49 // PostTaskAndReplyWithResult( 50 // target_thread_.message_loop_proxy(), 51 // FROM_HERE, 52 // Bind(&DoWorkAndReturn), 53 // Bind(&Callback)); 54 template <typename TaskReturnType, typename ReplyArgType> 55 bool PostTaskAndReplyWithResult( 56 TaskRunner* task_runner, 57 const tracked_objects::Location& from_here, 58 const Callback<TaskReturnType(void)>& task, 59 const Callback<void(ReplyArgType)>& reply) { 60 TaskReturnType* result = new TaskReturnType(); 61 return task_runner->PostTaskAndReply( 62 from_here, 63 base::Bind(&internal::ReturnAsParamAdapter<TaskReturnType>, task, 64 result), 65 base::Bind(&internal::ReplyAdapter<TaskReturnType, ReplyArgType>, reply, 66 base::Owned(result))); 67 } 68 69 } // namespace base 70 71 #endif // BASE_TASK_RUNNER_UTIL_H_ 72