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