blob: b6dd0f36d69f1f60efe1fde17426314e864a2bb5 [file] [log] [blame]
battre@chromium.org6d025972012-04-17 11:48:06 +09001// 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_
battre@chromium.org6d025972012-04-17 11:48:06 +09007
8#include "base/bind.h"
9#include "base/bind_helpers.h"
rsleevi@chromium.org85c5f232012-05-04 07:34:17 +090010#include "base/callback_internal.h"
battre@chromium.org6d025972012-04-17 11:48:06 +090011#include "base/logging.h"
12#include "base/task_runner.h"
13
14namespace base {
15
16namespace internal {
17
ajwong@chromium.orgb8102192012-11-28 12:29:01 +090018// Adapts a function that produces a result via a return value to
19// one that returns via an output parameter.
battre@chromium.org6d025972012-04-17 11:48:06 +090020template <typename ReturnType>
21void ReturnAsParamAdapter(const Callback<ReturnType(void)>& func,
22 ReturnType* result) {
ajwong@chromium.orgb8102192012-11-28 12:29:01 +090023 *result = func.Run();
battre@chromium.org6d025972012-04-17 11:48:06 +090024}
25
ajwong@chromium.orgb8102192012-11-28 12:29:01 +090026// 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())
rsleevi@chromium.org85c5f232012-05-04 07:34:17 +090035 callback.Run(CallbackForward(*result));
battre@chromium.org6d025972012-04-17 11:48:06 +090036}
37
battre@chromium.org6d025972012-04-17 11:48:06 +090038} // 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));
ajwong@chromium.orgb8102192012-11-28 12:29:01 +090054template <typename TaskReturnType, typename ReplyArgType>
battre@chromium.org6d025972012-04-17 11:48:06 +090055bool PostTaskAndReplyWithResult(
56 TaskRunner* task_runner,
57 const tracked_objects::Location& from_here,
ajwong@chromium.orgb8102192012-11-28 12:29:01 +090058 const Callback<TaskReturnType(void)>& task,
59 const Callback<void(ReplyArgType)>& reply) {
60 TaskReturnType* result = new TaskReturnType();
battre@chromium.org6d025972012-04-17 11:48:06 +090061 return task_runner->PostTaskAndReply(
62 from_here,
ajwong@chromium.orgb8102192012-11-28 12:29:01 +090063 base::Bind(&internal::ReturnAsParamAdapter<TaskReturnType>, task,
64 result),
65 base::Bind(&internal::ReplyAdapter<TaskReturnType, ReplyArgType>, reply,
66 base::Owned(result)));
battre@chromium.org6d025972012-04-17 11:48:06 +090067}
68
69} // namespace base
70
71#endif // BASE_TASK_RUNNER_UTIL_H_