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