Home | History | Annotate | Download | only in base
      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