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 14namespace base { 15 16namespace internal { 17 18// Adapts a function that produces a result via a return value to 19// one that returns via an output parameter. 20template <typename ReturnType> 21void 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. 27template <typename TaskReturnType, typename ReplyArgType> 28void 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_.task_runner(), 51// FROM_HERE, 52// Bind(&DoWorkAndReturn), 53// Bind(&Callback)); 54template <typename TaskReturnType, typename ReplyArgType> 55bool 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