task.h revision 201ade2fbba22bfb27ae029f4d23fca6ded109a0
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_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/non_thread_safe.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/raw_scoped_refptr_mismatch_checker.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/tracked.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/tuple.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/weak_ptr.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 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass 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 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass 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) { 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value), 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott badscopedrunnablemethodparams); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (obj_) 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DispatchToMethod(obj_.get(), meth_, params_); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Cancel() { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj_.reset(); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::WeakPtr<T> obj_; 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Method meth_; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Params params_; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(RunnableMethod); 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::WeakPtrFactory<T> weak_factory_; 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// General task implementations ------------------------------------------------ 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Task to delete an object 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<class T> 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass DeleteTask : public CancelableTask { 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch explicit DeleteTask(const T* obj) : obj_(obj) { 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete obj_; 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Cancel() { 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj_ = NULL; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 193513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const T* obj_; 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Task to Release() an object 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<class T> 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ReleaseTask : public CancelableTask { 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch explicit ReleaseTask(const T* obj) : obj_(obj) { 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (obj_) 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj_->Release(); 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Cancel() { 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj_ = NULL; 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 211513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const T* obj_; 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableMethodTraits -------------------------------------------------------- 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This traits-class is used by RunnableMethod to manage the lifetime of the 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// callee object. By default, it is assumed that the callee supports AddRef 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and Release methods. A particular class can specialize this template to 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// define other lifetime management. For example, if the callee is known to 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// live longer than the RunnableMethod object, then a RunnableMethodTraits 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// struct could be defined with empty RetainCallee and ReleaseCallee methods. 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// for declaring a RunnableMethodTraits that disables refcounting. 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T> 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct RunnableMethodTraits { 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RunnableMethodTraits() { 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott origin_thread_id_ = PlatformThread::CurrentId(); 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~RunnableMethodTraits() { 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If destroyed on a separate thread, then we had better have been using 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // thread-safe reference counting! 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (origin_thread_id_ != PlatformThread::CurrentId()) 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(T::ImplementsThreadSafeReferenceCounting()); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RetainCallee(T* obj) { 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Catch NewRunnableMethod being called in an object's constructor. This 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // isn't safe since the method can be invoked before the constructor 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // completes, causing the object to be deleted. 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj->AddRef(); 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj->Release(); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj->AddRef(); 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ReleaseCallee(T* obj) { 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj->Release(); 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PlatformThreadId origin_thread_id_; 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Convenience macro for declaring a RunnableMethodTraits that disables 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// refcounting of a class. This is useful if you know that the callee 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will outlive the RunnableMethod object and thus do not need the ref counts. 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// global namespace scope. Example: 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// namespace foo { 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// class Bar { 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ... 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// }; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// } // namespace foo 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// class. 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \ 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <> \ 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct RunnableMethodTraits<TypeName> { \ 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RetainCallee(TypeName* manager) {} \ 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ReleaseCallee(TypeName* manager) {} \ 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableMethod and RunnableFunction ----------------------------------------- 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Runnable methods are a type of task that call a function on an object when 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// they are run. We implement both an object and a set of NewRunnableMethod and 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NewRunnableFunction functions for convenience. These functions are 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// overloaded and will infer the template types, simplifying calling code. 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The template definitions all use the following names: 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// T - the class type of the object you're supplying 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// this is not needed for the Static version of the call 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Method/Function - the signature of a pointer to the method or function you 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// want to call 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Param - the parameter(s) to the method, possibly packed as a Tuple 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A - the first parameter (if any) to the method 3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// B - the second parameter (if any) to the method 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Put these all together and you get an object that can call a method whose 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// signature is: 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// R T::MyFunction([A[, B]]) 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Usage: 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]]) 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]]) 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableMethod and NewRunnableMethod implementation ------------------------- 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class Params> 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RunnableMethod : public CancelableTask { 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RunnableMethod(T* obj, Method meth, const Params& params) 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : obj_(obj), meth_(meth), params_(params) { 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott traits_.RetainCallee(obj_); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value), 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott badrunnablemethodparams); 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~RunnableMethod() { 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReleaseCallee(); 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (obj_) 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DispatchToMethod(obj_, meth_, params_); 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Cancel() { 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReleaseCallee(); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ReleaseCallee() { 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (obj_) { 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott traits_.ReleaseCallee(obj_); 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott obj_ = NULL; 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* obj_; 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Method meth_; 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Params params_; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RunnableMethodTraits<T> traits_; 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method> 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method) { 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple()); 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A> 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) { 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, Method, Tuple1<A> >(object, 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott method, 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a)); 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B> 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst A& a, const B& b) { 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, Method, Tuple2<A, B> >(object, method, 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b)); 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C> 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, const C& c) { 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, Method, Tuple3<A, B, C> >(object, method, 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, c)); 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D> 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c, const D& d) { 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method, 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott c, d)); 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D, class E> 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c, const D& d, const E& e) { 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Method, 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Tuple5<A, B, C, D, E> >(object, 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott method, 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, c, d, e)); 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D, class E, 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class F> 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c, const D& d, const E& e, 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const F& f) { 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Method, 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Tuple6<A, B, C, D, E, F> >(object, 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott method, 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, c, d, e, 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott f)); 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T, class Method, class A, class B, class C, class D, class E, 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class F, class G> 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableMethod(T* object, Method method, 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c, const D& d, const E& e, 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const F& f, const G& g) { 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableMethod<T, 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Method, 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Tuple7<A, B, C, D, E, F, G> >(object, 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott method, 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, c, d, 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott e, f, g)); 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunnableFunction and NewRunnableFunction implementation --------------------- 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class Params> 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RunnableFunction : public CancelableTask { 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RunnableFunction(Function function, const Params& params) 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : function_(function), params_(params) { 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott COMPILE_ASSERT((FunctionUsesScopedRefptrCorrectly<Function, Params>::value), 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott badrunnablefunctionparams); 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~RunnableFunction() { 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run() { 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (function_) 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DispatchToFunction(function_, params_); 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Cancel() { 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Function function_; 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Params params_; 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function> 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function) { 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableFunction<Function, Tuple0>(function, MakeTuple()); 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A> 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function, const A& a) { 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableFunction<Function, Tuple1<A> >(function, MakeTuple(a)); 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B> 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function, 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b) { 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableFunction<Function, Tuple2<A, B> >(function, 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b)); 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B, class C> 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function, 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c) { 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableFunction<Function, Tuple3<A, B, C> >(function, 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, c)); 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B, class C, class D> 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function, 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c, const D& d) { 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableFunction<Function, Tuple4<A, B, C, D> >(function, 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott c, d)); 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class Function, class A, class B, class C, class D, class E> 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline CancelableTask* NewRunnableFunction(Function function, 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const A& a, const B& b, 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const C& c, const D& d, 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const E& e) { 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return new RunnableFunction<Function, Tuple5<A, B, C, D, E> >(function, 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MakeTuple(a, b, 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott c, d, 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott e)); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class Function, class A, class B, class C, class D, class E, 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class F> 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline CancelableTask* NewRunnableFunction(Function function, 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const A& a, const B& b, 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const C& c, const D& d, 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const E& e, const F& f) { 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new RunnableFunction<Function, Tuple6<A, B, C, D, E, F> >(function, 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MakeTuple(a, b, c, d, e, f)); 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class Function, class A, class B, class C, class D, class E, 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class F, class G> 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline CancelableTask* NewRunnableFunction(Function function, 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const A& a, const B& b, 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const C& c, const D& d, 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const E& e, const F& f, 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const G& g) { 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new RunnableFunction<Function, Tuple7<A, B, C, D, E, F, G> >(function, 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MakeTuple(a, b, c, d, e, f, g)); 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class Function, class A, class B, class C, class D, class E, 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class F, class G, class H> 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline CancelableTask* NewRunnableFunction(Function function, 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const A& a, const B& b, 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const C& c, const D& d, 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const E& e, const F& f, 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const G& g, const H& h) { 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new RunnableFunction<Function, Tuple8<A, B, C, D, E, F, G, H> >( 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch function, MakeTuple(a, b, c, d, e, f, g, h)); 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // BASE_TASK_H_ 530