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