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