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 GOOGLE_APIS_DRIVE_TASK_UTIL_H_ 6#define GOOGLE_APIS_DRIVE_TASK_UTIL_H_ 7 8#include "base/bind.h" 9#include "base/message_loop/message_loop_proxy.h" 10 11namespace google_apis { 12 13// Runs task on a thread on which |task_runner| may run tasks. 14void RunTaskOnThread(scoped_refptr<base::SequencedTaskRunner> task_runner, 15 const base::Closure& task); 16 17namespace internal { 18 19// Implementation of the composed callback, whose signature is |Sig|. 20template<typename Sig> struct ComposedCallback; 21 22// ComposedCallback with no argument. 23template<> 24struct ComposedCallback<void()> { 25 static void Run( 26 const base::Callback<void(const base::Closure&)>& runner, 27 const base::Closure& callback) { 28 runner.Run(callback); 29 } 30}; 31 32// ComposedCallback with one argument. 33template<typename T1> 34struct ComposedCallback<void(T1)> { 35 static void Run( 36 const base::Callback<void(const base::Closure&)>& runner, 37 const base::Callback<void(T1)>& callback, 38 T1 arg1) { 39 runner.Run(base::Bind(callback, arg1)); 40 } 41}; 42 43// ComposedCallback with two arguments. 44template<typename T1, typename T2> 45struct ComposedCallback<void(T1, T2)> { 46 static void Run( 47 const base::Callback<void(const base::Closure&)>& runner, 48 const base::Callback<void(T1, T2)>& callback, 49 T1 arg1, T2 arg2) { 50 runner.Run(base::Bind(callback, arg1, arg2)); 51 } 52}; 53 54// ComposedCallback with two arguments, and the last one is scoped_ptr. 55template<typename T1, typename T2, typename D2> 56struct ComposedCallback<void(T1, scoped_ptr<T2, D2>)> { 57 static void Run( 58 const base::Callback<void(const base::Closure&)>& runner, 59 const base::Callback<void(T1, scoped_ptr<T2, D2>)>& callback, 60 T1 arg1, scoped_ptr<T2, D2> arg2) { 61 runner.Run(base::Bind(callback, arg1, base::Passed(&arg2))); 62 } 63}; 64 65// ComposedCallback with three arguments. 66template<typename T1, typename T2, typename T3> 67struct ComposedCallback<void(T1, T2, T3)> { 68 static void Run( 69 const base::Callback<void(const base::Closure&)>& runner, 70 const base::Callback<void(T1, T2, T3)>& callback, 71 T1 arg1, T2 arg2, T3 arg3) { 72 runner.Run(base::Bind(callback, arg1, arg2, arg3)); 73 } 74}; 75 76// ComposedCallback with three arguments, and the last one is scoped_ptr. 77template<typename T1, typename T2, typename T3, typename D3> 78struct ComposedCallback<void(T1, T2, scoped_ptr<T3, D3>)> { 79 static void Run( 80 const base::Callback<void(const base::Closure&)>& runner, 81 const base::Callback<void(T1, T2, scoped_ptr<T3, D3>)>& callback, 82 T1 arg1, T2 arg2, scoped_ptr<T3, D3> arg3) { 83 runner.Run(base::Bind(callback, arg1, arg2, base::Passed(&arg3))); 84 } 85}; 86 87// ComposedCallback with four arguments. 88template<typename T1, typename T2, typename T3, typename T4> 89struct ComposedCallback<void(T1, T2, T3, T4)> { 90 static void Run( 91 const base::Callback<void(const base::Closure&)>& runner, 92 const base::Callback<void(T1, T2, T3, T4)>& callback, 93 T1 arg1, T2 arg2, T3 arg3, T4 arg4) { 94 runner.Run(base::Bind(callback, arg1, arg2, arg3, arg4)); 95 } 96}; 97 98} // namespace internal 99 100// Returns callback that takes arguments (arg1, arg2, ...), create a closure 101// by binding them to |callback|, and runs |runner| with the closure. 102// I.e. the returned callback works as follows: 103// runner.Run(Bind(callback, arg1, arg2, ...)) 104template<typename CallbackType> 105CallbackType CreateComposedCallback( 106 const base::Callback<void(const base::Closure&)>& runner, 107 const CallbackType& callback) { 108 DCHECK(!runner.is_null()); 109 DCHECK(!callback.is_null()); 110 return base::Bind( 111 &internal::ComposedCallback<typename CallbackType::RunType>::Run, 112 runner, callback); 113} 114 115// Returns callback which runs the given |callback| on the current thread. 116template<typename CallbackType> 117CallbackType CreateRelayCallback(const CallbackType& callback) { 118 return CreateComposedCallback( 119 base::Bind(&RunTaskOnThread, base::MessageLoopProxy::current()), 120 callback); 121} 122 123} // namespace google_apis 124 125#endif // GOOGLE_APIS_DRIVE_TASK_UTIL_H_ 126