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 11 namespace google_apis { 12 13 // Runs task on the thread to which |task_runner| belongs. 14 void RunTaskOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner, 15 const base::Closure& task); 16 17 namespace internal { 18 19 // Implementation of the composed callback, whose signature is |Sig|. 20 template<typename Sig> struct ComposedCallback; 21 22 // ComposedCallback with no argument. 23 template<> 24 struct 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. 33 template<typename T1> 34 struct 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. 44 template<typename T1, typename T2> 45 struct 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. 55 template<typename T1, typename T2, typename D2> 56 struct 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. 66 template<typename T1, typename T2, typename T3> 67 struct 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. 77 template<typename T1, typename T2, typename T3, typename D3> 78 struct 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. 88 template<typename T1, typename T2, typename T3, typename T4> 89 struct 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 // ComposedCallback with four arguments, and the second one is scoped_ptr. 99 template<typename T1, typename T2, typename D2, typename T3, typename T4> 100 struct ComposedCallback<void(T1, scoped_ptr<T2, D2>, T3, T4)> { 101 static void Run( 102 const base::Callback<void(const base::Closure&)>& runner, 103 const base::Callback<void(T1, scoped_ptr<T2, D2>, T3, T4)>& callback, 104 T1 arg1, scoped_ptr<T2, D2> arg2, T3 arg3, T4 arg4) { 105 runner.Run(base::Bind(callback, arg1, base::Passed(&arg2), arg3, arg4)); 106 } 107 }; 108 109 } // namespace internal 110 111 // Returns callback that takes arguments (arg1, arg2, ...), create a closure 112 // by binding them to |callback|, and runs |runner| with the closure. 113 // I.e. the returned callback works as follows: 114 // runner.Run(Bind(callback, arg1, arg2, ...)) 115 template<typename CallbackType> 116 CallbackType CreateComposedCallback( 117 const base::Callback<void(const base::Closure&)>& runner, 118 const CallbackType& callback) { 119 DCHECK(!runner.is_null()); 120 DCHECK(!callback.is_null()); 121 return base::Bind( 122 &internal::ComposedCallback<typename CallbackType::RunType>::Run, 123 runner, callback); 124 } 125 126 // Returns callback which runs the given |callback| on the current thread. 127 template<typename CallbackType> 128 CallbackType CreateRelayCallback(const CallbackType& callback) { 129 return CreateComposedCallback( 130 base::Bind(&RunTaskOnThread, base::MessageLoopProxy::current()), 131 callback); 132 } 133 134 } // namespace google_apis 135 136 #endif // GOOGLE_APIS_DRIVE_TASK_UTIL_H_ 137