Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2009 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_H_
      6 #define BASE_TASK_H_
      7 
      8 #include "base/non_thread_safe.h"
      9 #include "base/raw_scoped_refptr_mismatch_checker.h"
     10 #include "base/tracked.h"
     11 #include "base/tuple.h"
     12 #include "base/weak_ptr.h"
     13 
     14 // Task ------------------------------------------------------------------------
     15 //
     16 // A task is a generic runnable thingy, usually used for running code on a
     17 // different thread or for scheduling future tasks off of the message loop.
     18 
     19 class Task : public tracked_objects::Tracked {
     20  public:
     21   Task() {}
     22   virtual ~Task() {}
     23 
     24   // Tasks are automatically deleted after Run is called.
     25   virtual void Run() = 0;
     26 };
     27 
     28 class CancelableTask : public Task {
     29  public:
     30   // Not all tasks support cancellation.
     31   virtual void Cancel() = 0;
     32 };
     33 
     34 // Scoped Factories ------------------------------------------------------------
     35 //
     36 // These scoped factory objects can be used by non-refcounted objects to safely
     37 // place tasks in a message loop.  Each factory guarantees that the tasks it
     38 // produces will not run after the factory is destroyed.  Commonly, factories
     39 // are declared as class members, so the class' tasks will automatically cancel
     40 // when the class instance is destroyed.
     41 //
     42 // Exampe Usage:
     43 //
     44 // class MyClass {
     45 //  private:
     46 //   // This factory will be used to schedule invocations of SomeMethod.
     47 //   ScopedRunnableMethodFactory<MyClass> some_method_factory_;
     48 //
     49 //  public:
     50 //   // It is safe to suppress warning 4355 here.
     51 //   MyClass() : some_method_factory_(this) { }
     52 //
     53 //   void SomeMethod() {
     54 //     // If this function might be called directly, you might want to revoke
     55 //     // any outstanding runnable methods scheduled to call it.  If it's not
     56 //     // referenced other than by the factory, this is unnecessary.
     57 //     some_method_factory_.RevokeAll();
     58 //     ...
     59 //   }
     60 //
     61 //   void ScheduleSomeMethod() {
     62 //     // If you'd like to only only have one pending task at a time, test for
     63 //     // |empty| before manufacturing another task.
     64 //     if (!some_method_factory_.empty())
     65 //       return;
     66 //
     67 //     // The factories are not thread safe, so always invoke on
     68 //     // |MessageLoop::current()|.
     69 //     MessageLoop::current()->PostDelayedTask(FROM_HERE,
     70 //         some_method_factory_.NewRunnableMethod(&MyClass::SomeMethod),
     71 //         kSomeMethodDelayMS);
     72 //   }
     73 // };
     74 
     75 // A ScopedRunnableMethodFactory creates runnable methods for a specified
     76 // object.  This is particularly useful for generating callbacks for
     77 // non-reference counted objects when the factory is a member of the object.
     78 template<class T>
     79 class ScopedRunnableMethodFactory {
     80  public:
     81   explicit ScopedRunnableMethodFactory(T* object) : weak_factory_(object) {
     82   }
     83 
     84   template <class Method>
     85   inline Task* NewRunnableMethod(Method method) {
     86     return new RunnableMethod<Method, Tuple0>(
     87         weak_factory_.GetWeakPtr(), method, MakeTuple());
     88   }
     89 
     90   template <class Method, class A>
     91   inline Task* NewRunnableMethod(Method method, const A& a) {
     92     return new RunnableMethod<Method, Tuple1<A> >(
     93         weak_factory_.GetWeakPtr(), method, MakeTuple(a));
     94   }
     95 
     96   template <class Method, class A, class B>
     97   inline Task* NewRunnableMethod(Method method, const A& a, const B& b) {
     98     return new RunnableMethod<Method, Tuple2<A, B> >(
     99         weak_factory_.GetWeakPtr(), method, MakeTuple(a, b));
    100   }
    101 
    102   template <class Method, class A, class B, class C>
    103   inline Task* NewRunnableMethod(Method method,
    104                                  const A& a,
    105                                  const B& b,
    106                                  const C& c) {
    107     return new RunnableMethod<Method, Tuple3<A, B, C> >(
    108         weak_factory_.GetWeakPtr(), method, MakeTuple(a, b, c));
    109   }
    110 
    111   template <class Method, class A, class B, class C, class D>
    112   inline Task* NewRunnableMethod(Method method,
    113                                  const A& a,
    114                                  const B& b,
    115                                  const C& c,
    116                                  const D& d) {
    117     return new RunnableMethod<Method, Tuple4<A, B, C, D> >(
    118         weak_factory_.GetWeakPtr(), method, MakeTuple(a, b, c, d));
    119   }
    120 
    121   template <class Method, class A, class B, class C, class D, class E>
    122   inline Task* NewRunnableMethod(Method method,
    123                                  const A& a,
    124                                  const B& b,
    125                                  const C& c,
    126                                  const D& d,
    127                                  const E& e) {
    128     return new RunnableMethod<Method, Tuple5<A, B, C, D, E> >(
    129         weak_factory_.GetWeakPtr(), method, MakeTuple(a, b, c, d, e));
    130   }
    131 
    132   void RevokeAll() { weak_factory_.InvalidateWeakPtrs(); }
    133 
    134   bool empty() const { return !weak_factory_.HasWeakPtrs(); }
    135 
    136  protected:
    137   template <class Method, class Params>
    138   class RunnableMethod : public Task {
    139    public:
    140     RunnableMethod(const base::WeakPtr<T>& obj, Method meth, const Params& params)
    141         : obj_(obj),
    142           meth_(meth),
    143           params_(params) {
    144       COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value),
    145                      badscopedrunnablemethodparams);
    146     }
    147 
    148     virtual void Run() {
    149       if (obj_)
    150         DispatchToMethod(obj_.get(), meth_, params_);
    151     }
    152 
    153    private:
    154     base::WeakPtr<T> obj_;
    155     Method meth_;
    156     Params params_;
    157 
    158     DISALLOW_COPY_AND_ASSIGN(RunnableMethod);
    159   };
    160 
    161  private:
    162   base::WeakPtrFactory<T> weak_factory_;
    163 };
    164 
    165 // General task implementations ------------------------------------------------
    166 
    167 // Task to delete an object
    168 template<class T>
    169 class DeleteTask : public CancelableTask {
    170  public:
    171   explicit DeleteTask(T* obj) : obj_(obj) {
    172   }
    173   virtual void Run() {
    174     delete obj_;
    175   }
    176   virtual void Cancel() {
    177     obj_ = NULL;
    178   }
    179  private:
    180   T* obj_;
    181 };
    182 
    183 // Task to Release() an object
    184 template<class T>
    185 class ReleaseTask : public CancelableTask {
    186  public:
    187   explicit ReleaseTask(T* obj) : obj_(obj) {
    188   }
    189   virtual void Run() {
    190     if (obj_)
    191       obj_->Release();
    192   }
    193   virtual void Cancel() {
    194     obj_ = NULL;
    195   }
    196  private:
    197   T* obj_;
    198 };
    199 
    200 // RunnableMethodTraits --------------------------------------------------------
    201 //
    202 // This traits-class is used by RunnableMethod to manage the lifetime of the
    203 // callee object.  By default, it is assumed that the callee supports AddRef
    204 // and Release methods.  A particular class can specialize this template to
    205 // define other lifetime management.  For example, if the callee is known to
    206 // live longer than the RunnableMethod object, then a RunnableMethodTraits
    207 // struct could be defined with empty RetainCallee and ReleaseCallee methods.
    208 
    209 template <class T>
    210 struct RunnableMethodTraits {
    211   RunnableMethodTraits() {
    212 #ifndef NDEBUG
    213     origin_thread_id_ = PlatformThread::CurrentId();
    214 #endif
    215   }
    216 
    217   ~RunnableMethodTraits() {
    218 #ifndef NDEBUG
    219     // If destroyed on a separate thread, then we had better have been using
    220     // thread-safe reference counting!
    221     if (origin_thread_id_ != PlatformThread::CurrentId())
    222       DCHECK(T::ImplementsThreadSafeReferenceCounting());
    223 #endif
    224   }
    225 
    226   void RetainCallee(T* obj) {
    227 #ifndef NDEBUG
    228     // Catch NewRunnableMethod being called in an object's constructor.  This
    229     // isn't safe since the method can be invoked before the constructor
    230     // completes, causing the object to be deleted.
    231     obj->AddRef();
    232     obj->Release();
    233 #endif
    234     obj->AddRef();
    235   }
    236 
    237   void ReleaseCallee(T* obj) {
    238     obj->Release();
    239   }
    240 
    241  private:
    242 #ifndef NDEBUG
    243   PlatformThreadId origin_thread_id_;
    244 #endif
    245 };
    246 
    247 // RunnableMethod and RunnableFunction -----------------------------------------
    248 //
    249 // Runnable methods are a type of task that call a function on an object when
    250 // they are run. We implement both an object and a set of NewRunnableMethod and
    251 // NewRunnableFunction functions for convenience. These functions are
    252 // overloaded and will infer the template types, simplifying calling code.
    253 //
    254 // The template definitions all use the following names:
    255 // T                - the class type of the object you're supplying
    256 //                    this is not needed for the Static version of the call
    257 // Method/Function  - the signature of a pointer to the method or function you
    258 //                    want to call
    259 // Param            - the parameter(s) to the method, possibly packed as a Tuple
    260 // A                - the first parameter (if any) to the method
    261 // B                - the second parameter (if any) to the mathod
    262 //
    263 // Put these all together and you get an object that can call a method whose
    264 // signature is:
    265 //   R T::MyFunction([A[, B]])
    266 //
    267 // Usage:
    268 // PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]])
    269 // PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]])
    270 
    271 // RunnableMethod and NewRunnableMethod implementation -------------------------
    272 
    273 template <class T, class Method, class Params>
    274 class RunnableMethod : public CancelableTask {
    275  public:
    276   RunnableMethod(T* obj, Method meth, const Params& params)
    277       : obj_(obj), meth_(meth), params_(params) {
    278     traits_.RetainCallee(obj_);
    279     COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value),
    280                    badrunnablemethodparams);
    281   }
    282 
    283   ~RunnableMethod() {
    284     ReleaseCallee();
    285   }
    286 
    287   virtual void Run() {
    288     if (obj_)
    289       DispatchToMethod(obj_, meth_, params_);
    290   }
    291 
    292   virtual void Cancel() {
    293     ReleaseCallee();
    294   }
    295 
    296  private:
    297   void ReleaseCallee() {
    298     if (obj_) {
    299       traits_.ReleaseCallee(obj_);
    300       obj_ = NULL;
    301     }
    302   }
    303 
    304   T* obj_;
    305   Method meth_;
    306   Params params_;
    307   RunnableMethodTraits<T> traits_;
    308 };
    309 
    310 template <class T, class Method>
    311 inline CancelableTask* NewRunnableMethod(T* object, Method method) {
    312   return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple());
    313 }
    314 
    315 template <class T, class Method, class A>
    316 inline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) {
    317   return new RunnableMethod<T, Method, Tuple1<A> >(object,
    318                                                    method,
    319                                                    MakeTuple(a));
    320 }
    321 
    322 template <class T, class Method, class A, class B>
    323 inline CancelableTask* NewRunnableMethod(T* object, Method method,
    324 const A& a, const B& b) {
    325   return new RunnableMethod<T, Method, Tuple2<A, B> >(object, method,
    326                                                       MakeTuple(a, b));
    327 }
    328 
    329 template <class T, class Method, class A, class B, class C>
    330 inline CancelableTask* NewRunnableMethod(T* object, Method method,
    331                                           const A& a, const B& b, const C& c) {
    332   return new RunnableMethod<T, Method, Tuple3<A, B, C> >(object, method,
    333                                                          MakeTuple(a, b, c));
    334 }
    335 
    336 template <class T, class Method, class A, class B, class C, class D>
    337 inline CancelableTask* NewRunnableMethod(T* object, Method method,
    338                                           const A& a, const B& b,
    339                                           const C& c, const D& d) {
    340   return new RunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method,
    341                                                             MakeTuple(a, b,
    342                                                                       c, d));
    343 }
    344 
    345 template <class T, class Method, class A, class B, class C, class D, class E>
    346 inline CancelableTask* NewRunnableMethod(T* object, Method method,
    347                                           const A& a, const B& b,
    348                                           const C& c, const D& d, const E& e) {
    349   return new RunnableMethod<T,
    350                             Method,
    351                             Tuple5<A, B, C, D, E> >(object,
    352                                                     method,
    353                                                     MakeTuple(a, b, c, d, e));
    354 }
    355 
    356 template <class T, class Method, class A, class B, class C, class D, class E,
    357           class F>
    358 inline CancelableTask* NewRunnableMethod(T* object, Method method,
    359                                           const A& a, const B& b,
    360                                           const C& c, const D& d, const E& e,
    361                                           const F& f) {
    362   return new RunnableMethod<T,
    363                             Method,
    364                             Tuple6<A, B, C, D, E, F> >(object,
    365                                                        method,
    366                                                        MakeTuple(a, b, c, d, e,
    367                                                                  f));
    368 }
    369 
    370 template <class T, class Method, class A, class B, class C, class D, class E,
    371           class F, class G>
    372 inline CancelableTask* NewRunnableMethod(T* object, Method method,
    373                                          const A& a, const B& b,
    374                                          const C& c, const D& d, const E& e,
    375                                          const F& f, const G& g) {
    376   return new RunnableMethod<T,
    377                             Method,
    378                             Tuple7<A, B, C, D, E, F, G> >(object,
    379                                                           method,
    380                                                           MakeTuple(a, b, c, d,
    381                                                                     e, f, g));
    382 }
    383 
    384 // RunnableFunction and NewRunnableFunction implementation ---------------------
    385 
    386 template <class Function, class Params>
    387 class RunnableFunction : public CancelableTask {
    388  public:
    389   RunnableFunction(Function function, const Params& params)
    390       : function_(function), params_(params) {
    391     COMPILE_ASSERT((FunctionUsesScopedRefptrCorrectly<Function, Params>::value),
    392                    badrunnablefunctionparams);
    393   }
    394 
    395   ~RunnableFunction() {
    396   }
    397 
    398   virtual void Run() {
    399     if (function_)
    400       DispatchToFunction(function_, params_);
    401   }
    402 
    403   virtual void Cancel() {
    404   }
    405 
    406  private:
    407   Function function_;
    408   Params params_;
    409 };
    410 
    411 template <class Function>
    412 inline CancelableTask* NewRunnableFunction(Function function) {
    413   return new RunnableFunction<Function, Tuple0>(function, MakeTuple());
    414 }
    415 
    416 template <class Function, class A>
    417 inline CancelableTask* NewRunnableFunction(Function function, const A& a) {
    418   return new RunnableFunction<Function, Tuple1<A> >(function, MakeTuple(a));
    419 }
    420 
    421 template <class Function, class A, class B>
    422 inline CancelableTask* NewRunnableFunction(Function function,
    423                                            const A& a, const B& b) {
    424   return new RunnableFunction<Function, Tuple2<A, B> >(function,
    425                                                        MakeTuple(a, b));
    426 }
    427 
    428 template <class Function, class A, class B, class C>
    429 inline CancelableTask* NewRunnableFunction(Function function,
    430                                            const A& a, const B& b,
    431                                            const C& c) {
    432   return new RunnableFunction<Function, Tuple3<A, B, C> >(function,
    433                                                           MakeTuple(a, b, c));
    434 }
    435 
    436 template <class Function, class A, class B, class C, class D>
    437 inline CancelableTask* NewRunnableFunction(Function function,
    438                                            const A& a, const B& b,
    439                                            const C& c, const D& d) {
    440   return new RunnableFunction<Function, Tuple4<A, B, C, D> >(function,
    441                                                              MakeTuple(a, b,
    442                                                                        c, d));
    443 }
    444 
    445 template <class Function, class A, class B, class C, class D, class E>
    446 inline CancelableTask* NewRunnableFunction(Function function,
    447                                            const A& a, const B& b,
    448                                            const C& c, const D& d,
    449                                            const E& e) {
    450   return new RunnableFunction<Function, Tuple5<A, B, C, D, E> >(function,
    451                                                                 MakeTuple(a, b,
    452                                                                           c, d,
    453                                                                           e));
    454 }
    455 
    456 // Callback --------------------------------------------------------------------
    457 //
    458 // A Callback is like a Task but with unbound parameters. It is basically an
    459 // object-oriented function pointer.
    460 //
    461 // Callbacks are designed to work with Tuples.  A set of helper functions and
    462 // classes is provided to hide the Tuple details from the consumer.  Client
    463 // code will generally work with the CallbackRunner base class, which merely
    464 // provides a Run method and is returned by the New* functions. This allows
    465 // users to not care which type of class implements the callback, only that it
    466 // has a certain number and type of arguments.
    467 //
    468 // The implementation of this is done by CallbackImpl, which inherits
    469 // CallbackStorage to store the data. This allows the storage of the data
    470 // (requiring the class type T) to be hidden from users, who will want to call
    471 // this regardless of the implementor's type T.
    472 //
    473 // Note that callbacks currently have no facility for cancelling or abandoning
    474 // them. We currently handle this at a higher level for cases where this is
    475 // necessary. The pointer in a callback must remain valid until the callback
    476 // is made.
    477 //
    478 // Like Task, the callback executor is responsible for deleting the callback
    479 // pointer once the callback has executed.
    480 //
    481 // Example client usage:
    482 //   void Object::DoStuff(int, string);
    483 //   Callback2<int, string>::Type* callback =
    484 //       NewCallback(obj, &Object::DoStuff);
    485 //   callback->Run(5, string("hello"));
    486 //   delete callback;
    487 // or, equivalently, using tuples directly:
    488 //   CallbackRunner<Tuple2<int, string> >* callback =
    489 //       NewCallback(obj, &Object::DoStuff);
    490 //   callback->RunWithParams(MakeTuple(5, string("hello")));
    491 //
    492 // There is also a 0-args version that returns a value.  Example:
    493 //   int Object::GetNextInt();
    494 //   CallbackWithReturnValue<int>::Type* callback =
    495 //       NewCallbackWithReturnValue(obj, &Object::GetNextInt);
    496 //   int next_int = callback->Run();
    497 //   delete callback;
    498 
    499 // Base for all Callbacks that handles storage of the pointers.
    500 template <class T, typename Method>
    501 class CallbackStorage {
    502  public:
    503   CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) {
    504   }
    505 
    506  protected:
    507   T* obj_;
    508   Method meth_;
    509 };
    510 
    511 // Interface that is exposed to the consumer, that does the actual calling
    512 // of the method.
    513 template <typename Params>
    514 class CallbackRunner {
    515  public:
    516   typedef Params TupleType;
    517 
    518   virtual ~CallbackRunner() {}
    519   virtual void RunWithParams(const Params& params) = 0;
    520 
    521   // Convenience functions so callers don't have to deal with Tuples.
    522   inline void Run() {
    523     RunWithParams(Tuple0());
    524   }
    525 
    526   template <typename Arg1>
    527   inline void Run(const Arg1& a) {
    528     RunWithParams(Params(a));
    529   }
    530 
    531   template <typename Arg1, typename Arg2>
    532   inline void Run(const Arg1& a, const Arg2& b) {
    533     RunWithParams(Params(a, b));
    534   }
    535 
    536   template <typename Arg1, typename Arg2, typename Arg3>
    537   inline void Run(const Arg1& a, const Arg2& b, const Arg3& c) {
    538     RunWithParams(Params(a, b, c));
    539   }
    540 
    541   template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
    542   inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) {
    543     RunWithParams(Params(a, b, c, d));
    544   }
    545 
    546   template <typename Arg1, typename Arg2, typename Arg3,
    547             typename Arg4, typename Arg5>
    548   inline void Run(const Arg1& a, const Arg2& b, const Arg3& c,
    549                   const Arg4& d, const Arg5& e) {
    550     RunWithParams(Params(a, b, c, d, e));
    551   }
    552 };
    553 
    554 template <class T, typename Method, typename Params>
    555 class CallbackImpl : public CallbackStorage<T, Method>,
    556                      public CallbackRunner<Params> {
    557  public:
    558   CallbackImpl(T* obj, Method meth) : CallbackStorage<T, Method>(obj, meth) {
    559   }
    560   virtual void RunWithParams(const Params& params) {
    561     // use "this->" to force C++ to look inside our templatized base class; see
    562     // Effective C++, 3rd Ed, item 43, p210 for details.
    563     DispatchToMethod(this->obj_, this->meth_, params);
    564   }
    565 };
    566 
    567 // 0-arg implementation
    568 struct Callback0 {
    569   typedef CallbackRunner<Tuple0> Type;
    570 };
    571 
    572 template <class T>
    573 typename Callback0::Type* NewCallback(T* object, void (T::*method)()) {
    574   return new CallbackImpl<T, void (T::*)(), Tuple0 >(object, method);
    575 }
    576 
    577 // 1-arg implementation
    578 template <typename Arg1>
    579 struct Callback1 {
    580   typedef CallbackRunner<Tuple1<Arg1> > Type;
    581 };
    582 
    583 template <class T, typename Arg1>
    584 typename Callback1<Arg1>::Type* NewCallback(T* object,
    585                                             void (T::*method)(Arg1)) {
    586   return new CallbackImpl<T, void (T::*)(Arg1), Tuple1<Arg1> >(object, method);
    587 }
    588 
    589 // 2-arg implementation
    590 template <typename Arg1, typename Arg2>
    591 struct Callback2 {
    592   typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type;
    593 };
    594 
    595 template <class T, typename Arg1, typename Arg2>
    596 typename Callback2<Arg1, Arg2>::Type* NewCallback(
    597     T* object,
    598     void (T::*method)(Arg1, Arg2)) {
    599   return new CallbackImpl<T, void (T::*)(Arg1, Arg2),
    600       Tuple2<Arg1, Arg2> >(object, method);
    601 }
    602 
    603 // 3-arg implementation
    604 template <typename Arg1, typename Arg2, typename Arg3>
    605 struct Callback3 {
    606   typedef CallbackRunner<Tuple3<Arg1, Arg2, Arg3> > Type;
    607 };
    608 
    609 template <class T, typename Arg1, typename Arg2, typename Arg3>
    610 typename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback(
    611     T* object,
    612     void (T::*method)(Arg1, Arg2, Arg3)) {
    613   return new CallbackImpl<T,  void (T::*)(Arg1, Arg2, Arg3),
    614       Tuple3<Arg1, Arg2, Arg3> >(object, method);
    615 }
    616 
    617 // 4-arg implementation
    618 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
    619 struct Callback4 {
    620   typedef CallbackRunner<Tuple4<Arg1, Arg2, Arg3, Arg4> > Type;
    621 };
    622 
    623 template <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
    624 typename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback(
    625     T* object,
    626     void (T::*method)(Arg1, Arg2, Arg3, Arg4)) {
    627   return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4),
    628       Tuple4<Arg1, Arg2, Arg3, Arg4> >(object, method);
    629 }
    630 
    631 // 5-arg implementation
    632 template <typename Arg1, typename Arg2, typename Arg3,
    633           typename Arg4, typename Arg5>
    634 struct Callback5 {
    635   typedef CallbackRunner<Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> > Type;
    636 };
    637 
    638 template <class T, typename Arg1, typename Arg2,
    639           typename Arg3, typename Arg4, typename Arg5>
    640 typename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback(
    641     T* object,
    642     void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) {
    643   return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5),
    644       Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >(object, method);
    645 }
    646 
    647 // An UnboundMethod is a wrapper for a method where the actual object is
    648 // provided at Run dispatch time.
    649 template <class T, class Method, class Params>
    650 class UnboundMethod {
    651  public:
    652   UnboundMethod(Method m, Params p) : m_(m), p_(p) {
    653     COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value),
    654                    badunboundmethodparams);
    655   }
    656   void Run(T* obj) const {
    657     DispatchToMethod(obj, m_, p_);
    658   }
    659  private:
    660   Method m_;
    661   Params p_;
    662 };
    663 
    664 // Return value implementation with no args.
    665 template <typename ReturnValue>
    666 struct CallbackWithReturnValue {
    667   class Type {
    668    public:
    669     virtual ~Type() {}
    670     virtual ReturnValue Run() = 0;
    671   };
    672 };
    673 
    674 template <class T, typename Method, typename ReturnValue>
    675 class CallbackWithReturnValueImpl
    676     : public CallbackStorage<T, Method>,
    677       public CallbackWithReturnValue<ReturnValue>::Type {
    678  public:
    679   CallbackWithReturnValueImpl(T* obj, Method meth)
    680       : CallbackStorage<T, Method>(obj, meth) {}
    681 
    682   virtual ReturnValue Run() {
    683     return (this->obj_->*(this->meth_))();
    684   }
    685 
    686  protected:
    687   virtual ~CallbackWithReturnValueImpl() {}
    688 };
    689 
    690 template <class T, typename ReturnValue>
    691 typename CallbackWithReturnValue<ReturnValue>::Type*
    692 NewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) {
    693   return new CallbackWithReturnValueImpl<T, ReturnValue (T::*)(), ReturnValue>(
    694       object, method);
    695 }
    696 
    697 
    698 #endif  // BASE_TASK_H_
    699