1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_TASK_H_
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_TASK_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/weak_ptr.h"
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/tracked.h"
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/tuple.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Task ------------------------------------------------------------------------
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A task is a generic runnable thingy, usually used for running code on a
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// different thread or for scheduling future tasks off of the message loop.
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API Task : public tracked_objects::Tracked {
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Task();
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~Task();
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Tasks are automatically deleted after Run is called.
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Run() = 0;
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API CancelableTask : public Task {
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CancelableTask();
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~CancelableTask();
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Not all tasks support cancellation.
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Cancel() = 0;
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Scoped Factories ------------------------------------------------------------
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// These scoped factory objects can be used by non-refcounted objects to safely
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// place tasks in a message loop.  Each factory guarantees that the tasks it
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// produces will not run after the factory is destroyed.  Commonly, factories
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// are declared as class members, so the class' tasks will automatically cancel
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// when the class instance is destroyed.
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Exampe Usage:
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// class MyClass {
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//  private:
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   // This factory will be used to schedule invocations of SomeMethod.
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   ScopedRunnableMethodFactory<MyClass> some_method_factory_;
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//  public:
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   // It is safe to suppress warning 4355 here.
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   MyClass() : ALLOW_THIS_IN_INITIALIZER_LIST(some_method_factory_(this)) { }
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   void SomeMethod() {
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // If this function might be called directly, you might want to revoke
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // any outstanding runnable methods scheduled to call it.  If it's not
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // referenced other than by the factory, this is unnecessary.
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     some_method_factory_.RevokeAll();
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     ...
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   }
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   void ScheduleSomeMethod() {
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // If you'd like to only only have one pending task at a time, test for
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // |empty| before manufacturing another task.
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     if (!some_method_factory_.empty())
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//       return;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // The factories are not thread safe, so always invoke on
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//     // |MessageLoop::current()|.
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//     MessageLoop::current()->PostDelayedTask(
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//         FROM_HERE,
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//         some_method_factory_.NewRunnableMethod(&MyClass::SomeMethod),
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//         kSomeMethodDelayMS);
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   }
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// };
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A ScopedRunnableMethodFactory creates runnable methods for a specified
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// object.  This is particularly useful for generating callbacks for
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// non-reference counted objects when the factory is a member of the object.
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<class T>
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ScopedRunnableMethodFactory {
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit ScopedRunnableMethodFactory(T* object) : weak_factory_(object) {
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method>
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline CancelableTask* NewRunnableMethod(Method method) {
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new RunnableMethod<Method, Tuple0>(
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        weak_factory_.GetWeakPtr(), method, MakeTuple());
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method, class A>
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline CancelableTask* NewRunnableMethod(Method method, const A& a) {
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new RunnableMethod<Method, Tuple1<A> >(
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        weak_factory_.GetWeakPtr(), method, MakeTuple(a));
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method, class A, class B>
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline CancelableTask* NewRunnableMethod(Method method, const A& a,
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const B& b) {
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new RunnableMethod<Method, Tuple2<A, B> >(
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        weak_factory_.GetWeakPtr(), method, MakeTuple(a, b));
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method, class A, class B, class C>
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline CancelableTask* NewRunnableMethod(Method method,
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const A& a,
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const B& b,
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const C& c) {
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new RunnableMethod<Method, Tuple3<A, B, C> >(
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        weak_factory_.GetWeakPtr(), method, MakeTuple(a, b, c));
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method, class A, class B, class C, class D>
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline CancelableTask* NewRunnableMethod(Method method,
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const A& a,
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const B& b,
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const C& c,
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const D& d) {
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new RunnableMethod<Method, Tuple4<A, B, C, D> >(
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        weak_factory_.GetWeakPtr(), method, MakeTuple(a, b, c, d));
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method, class A, class B, class C, class D, class E>
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline CancelableTask* NewRunnableMethod(Method method,
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const A& a,
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const B& b,
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const C& c,
1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const D& d,
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           const E& e) {
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new RunnableMethod<Method, Tuple5<A, B, C, D, E> >(
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        weak_factory_.GetWeakPtr(), method, MakeTuple(a, b, c, d, e));
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RevokeAll() { weak_factory_.InvalidateWeakPtrs(); }
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool empty() const { return !weak_factory_.HasWeakPtrs(); }
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class Method, class Params>
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class RunnableMethod : public CancelableTask {
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    RunnableMethod(const base::WeakPtr<T>& obj,
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   Method meth,
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   const Params& params)
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        : obj_(obj),
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          meth_(meth),
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          params_(params) {
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      COMPILE_ASSERT(
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value),
15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          badscopedrunnablemethodparams);
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    virtual void Run() {
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (obj_)
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        DispatchToMethod(obj_.get(), meth_, params_);
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void Cancel() {
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      obj_.reset();
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   private:
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    base::WeakPtr<T> obj_;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Method meth_;
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Params params_;
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DISALLOW_COPY_AND_ASSIGN(RunnableMethod);
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::WeakPtrFactory<T> weak_factory_;
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// General task implementations ------------------------------------------------
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Task to delete an object
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<class T>
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass DeleteTask : public CancelableTask {
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  explicit DeleteTask(const T* obj) : obj_(obj) {
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Run() {
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete obj_;
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Cancel() {
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    obj_ = NULL;
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const T* obj_;
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Task to Release() an object
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<class T>
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ReleaseTask : public CancelableTask {
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
201513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  explicit ReleaseTask(const T* obj) : obj_(obj) {
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Run() {
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (obj_)
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      obj_->Release();
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Cancel() {
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    obj_ = NULL;
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const T* obj_;
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableMethodTraits --------------------------------------------------------
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This traits-class is used by RunnableMethod to manage the lifetime of the
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// callee object.  By default, it is assumed that the callee supports AddRef
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and Release methods.  A particular class can specialize this template to
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// define other lifetime management.  For example, if the callee is known to
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// live longer than the RunnableMethod object, then a RunnableMethodTraits
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// struct could be defined with empty RetainCallee and ReleaseCallee methods.
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// for declaring a RunnableMethodTraits that disables refcounting.
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T>
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct RunnableMethodTraits {
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunnableMethodTraits() {
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG
2313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    origin_thread_id_ = base::PlatformThread::CurrentId();
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~RunnableMethodTraits() {
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // If destroyed on a separate thread, then we had better have been using
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // thread-safe reference counting!
2393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (origin_thread_id_ != base::PlatformThread::CurrentId())
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DCHECK(T::ImplementsThreadSafeReferenceCounting());
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RetainCallee(T* obj) {
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Catch NewRunnableMethod being called in an object's constructor.  This
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // isn't safe since the method can be invoked before the constructor
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // completes, causing the object to be deleted.
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    obj->AddRef();
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    obj->Release();
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    obj->AddRef();
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ReleaseCallee(T* obj) {
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    obj->Release();
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG
2613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThreadId origin_thread_id_;
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Convenience macro for declaring a RunnableMethodTraits that disables
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// refcounting of a class.  This is useful if you know that the callee
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will outlive the RunnableMethod object and thus do not need the ref counts.
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// global namespace scope.  Example:
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   namespace foo {
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   class Bar {
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//     ...
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   };
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   }  // namespace foo
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch//   DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar);
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// class.
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  template <>                                      \
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct RunnableMethodTraits<TypeName> {          \
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void RetainCallee(TypeName* manager) {}        \
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void ReleaseCallee(TypeName* manager) {}       \
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableMethod and RunnableFunction -----------------------------------------
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Runnable methods are a type of task that call a function on an object when
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// they are run. We implement both an object and a set of NewRunnableMethod and
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NewRunnableFunction functions for convenience. These functions are
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// overloaded and will infer the template types, simplifying calling code.
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The template definitions all use the following names:
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// T                - the class type of the object you're supplying
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//                    this is not needed for the Static version of the call
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Method/Function  - the signature of a pointer to the method or function you
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//                    want to call
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Param            - the parameter(s) to the method, possibly packed as a Tuple
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A                - the first parameter (if any) to the method
3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// B                - the second parameter (if any) to the method
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Put these all together and you get an object that can call a method whose
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// signature is:
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   R T::MyFunction([A[, B]])
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Usage:
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]])
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]])
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableMethod and NewRunnableMethod implementation -------------------------
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class Params>
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RunnableMethod : public CancelableTask {
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunnableMethod(T* obj, Method meth, const Params& params)
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : obj_(obj), meth_(meth), params_(params) {
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    traits_.RetainCallee(obj_);
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    COMPILE_ASSERT(
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value),
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        badrunnablemethodparams);
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~RunnableMethod() {
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReleaseCallee();
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Run() {
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (obj_)
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DispatchToMethod(obj_, meth_, params_);
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Cancel() {
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReleaseCallee();
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ReleaseCallee() {
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    T* obj = obj_;
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    obj_ = NULL;
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (obj)
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      traits_.ReleaseCallee(obj);
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  T* obj_;
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Method meth_;
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Params params_;
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunnableMethodTraits<T> traits_;
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method>
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method) {
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple());
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A>
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) {
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T, Method, Tuple1<A> >(object,
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                   method,
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                   MakeTuple(a));
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B>
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method,
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst A& a, const B& b) {
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T, Method, Tuple2<A, B> >(object, method,
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                      MakeTuple(a, b));
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C>
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method,
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const A& a, const B& b, const C& c) {
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T, Method, Tuple3<A, B, C> >(object, method,
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                         MakeTuple(a, b, c));
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D>
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method,
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const A& a, const B& b,
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const C& c, const D& d) {
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method,
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                            MakeTuple(a, b,
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                      c, d));
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D, class E>
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method,
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const A& a, const B& b,
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const C& c, const D& d, const E& e) {
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T,
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Method,
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Tuple5<A, B, C, D, E> >(object,
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    method,
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    MakeTuple(a, b, c, d, e));
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D, class E,
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          class F>
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method,
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const A& a, const B& b,
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const C& c, const D& d, const E& e,
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          const F& f) {
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T,
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Method,
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Tuple6<A, B, C, D, E, F> >(object,
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                       method,
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                       MakeTuple(a, b, c, d, e,
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                 f));
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D, class E,
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          class F, class G>
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method,
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const A& a, const B& b,
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const C& c, const D& d, const E& e,
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const F& f, const G& g) {
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableMethod<T,
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Method,
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Tuple7<A, B, C, D, E, F, G> >(object,
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                          method,
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                          MakeTuple(a, b, c, d,
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                    e, f, g));
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
427dc0f95d653279beabeb9817299e2902918ba123eKristian Monsentemplate <class T, class Method, class A, class B, class C, class D, class E,
428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          class F, class G, class H>
429dc0f95d653279beabeb9817299e2902918ba123eKristian Monseninline CancelableTask* NewRunnableMethod(T* object, Method method,
430dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         const A& a, const B& b,
431dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         const C& c, const D& d, const E& e,
432dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         const F& f, const G& g, const H& h) {
433dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return new RunnableMethod<T,
434dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                            Method,
435dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                            Tuple8<A, B, C, D, E, F, G, H> >(object,
436dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                             method,
437dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                             MakeTuple(a, b, c,
438dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                                       d, e, f,
439dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                                       g, h));
440dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
441dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableFunction and NewRunnableFunction implementation ---------------------
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class Params>
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RunnableFunction : public CancelableTask {
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunnableFunction(Function function, const Params& params)
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : function_(function), params_(params) {
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    COMPILE_ASSERT(
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value),
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        badrunnablefunctionparams);
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~RunnableFunction() {
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Run() {
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (function_)
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DispatchToFunction(function_, params_);
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Cancel() {
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Function function_;
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Params params_;
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function>
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function) {
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableFunction<Function, Tuple0>(function, MakeTuple());
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A>
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function, const A& a) {
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableFunction<Function, Tuple1<A> >(function, MakeTuple(a));
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B>
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function,
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const A& a, const B& b) {
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableFunction<Function, Tuple2<A, B> >(function,
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                       MakeTuple(a, b));
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B, class C>
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function,
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const A& a, const B& b,
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const C& c) {
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableFunction<Function, Tuple3<A, B, C> >(function,
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                          MakeTuple(a, b, c));
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B, class C, class D>
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function,
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const A& a, const B& b,
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const C& c, const D& d) {
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableFunction<Function, Tuple4<A, B, C, D> >(function,
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                             MakeTuple(a, b,
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                       c, d));
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B, class C, class D, class E>
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function,
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const A& a, const B& b,
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const C& c, const D& d,
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const E& e) {
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return new RunnableFunction<Function, Tuple5<A, B, C, D, E> >(function,
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                MakeTuple(a, b,
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                          c, d,
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                                          e));
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class Function, class A, class B, class C, class D, class E,
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          class F>
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline CancelableTask* NewRunnableFunction(Function function,
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const A& a, const B& b,
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const C& c, const D& d,
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const E& e, const F& f) {
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new RunnableFunction<Function, Tuple6<A, B, C, D, E, F> >(function,
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MakeTuple(a, b, c, d, e, f));
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class Function, class A, class B, class C, class D, class E,
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          class F, class G>
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline CancelableTask* NewRunnableFunction(Function function,
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const A& a, const B& b,
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const C& c, const D& d,
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const E& e, const F& f,
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const G& g) {
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new RunnableFunction<Function, Tuple7<A, B, C, D, E, F, G> >(function,
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MakeTuple(a, b, c, d, e, f, g));
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class Function, class A, class B, class C, class D, class E,
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          class F, class G, class H>
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline CancelableTask* NewRunnableFunction(Function function,
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const A& a, const B& b,
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const C& c, const D& d,
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const E& e, const F& f,
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const G& g, const H& h) {
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new RunnableFunction<Function, Tuple8<A, B, C, D, E, F, G, H> >(
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      function, MakeTuple(a, b, c, d, e, f, g, h));
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // BASE_TASK_H_
548