Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #ifndef mozilla_plugins_TaskFactory_h
6 : #define mozilla_plugins_TaskFactory_h
7 :
8 : #include <base/task.h>
9 :
10 : #include "mozilla/Move.h"
11 :
12 : /*
13 : * This is based on the ScopedRunnableMethodFactory from ipc/chromium/src/base/task.h
14 : * Chromium's factories assert if tasks are created and run on different threads,
15 : * which is something we need to do in PluginModuleParent (hang UI vs. main thread).
16 : * TaskFactory just provides cancellable tasks that don't assert this.
17 : * This version also allows both ScopedMethod and regular Tasks to be generated
18 : * by the same Factory object.
19 : */
20 :
21 : namespace mozilla {
22 : namespace ipc {
23 :
24 : template<class T>
25 0 : class TaskFactory : public RevocableStore
26 : {
27 : private:
28 : template<class TaskType>
29 0 : class TaskWrapper : public TaskType
30 : {
31 : public:
32 : template<typename... Args>
33 0 : explicit TaskWrapper(RevocableStore* store, Args&&... args)
34 0 : : TaskType(mozilla::Forward<Args>(args)...)
35 0 : , revocable_(store)
36 : {
37 0 : }
38 :
39 0 : NS_IMETHOD Run() override {
40 0 : if (!revocable_.revoked())
41 0 : TaskType::Run();
42 0 : return NS_OK;
43 : }
44 :
45 : private:
46 : Revocable revocable_;
47 : };
48 :
49 : public:
50 3 : explicit TaskFactory(T* object) : object_(object) { }
51 :
52 : template <typename TaskParamType, typename... Args>
53 : inline already_AddRefed<TaskParamType> NewTask(Args&&... args)
54 : {
55 : typedef TaskWrapper<TaskParamType> TaskWrapper;
56 : RefPtr<TaskWrapper> task =
57 : new TaskWrapper(this, mozilla::Forward<Args>(args)...);
58 : return task.forget();
59 : }
60 :
61 : template <class Method, typename... Args>
62 : inline already_AddRefed<Runnable>
63 0 : NewRunnableMethod(Method method, Args&&... args) {
64 : typedef decltype(base::MakeTuple(mozilla::Forward<Args>(args)...)) ArgTuple;
65 : typedef RunnableMethod<Method, ArgTuple> RunnableMethod;
66 : typedef TaskWrapper<RunnableMethod> TaskWrapper;
67 :
68 : RefPtr<TaskWrapper> task =
69 0 : new TaskWrapper(this, object_, method,
70 0 : base::MakeTuple(mozilla::Forward<Args>(args)...));
71 :
72 0 : return task.forget();
73 : }
74 :
75 : protected:
76 : template <class Method, class Params>
77 0 : class RunnableMethod : public Runnable {
78 : public:
79 0 : RunnableMethod(T* obj, Method meth, const Params& params)
80 : : Runnable("ipc::TaskFactory::RunnableMethod")
81 : , obj_(obj)
82 : , meth_(meth)
83 0 : , params_(params)
84 : {
85 0 : }
86 :
87 0 : NS_IMETHOD Run() override {
88 0 : DispatchToMethod(obj_, meth_, params_);
89 0 : return NS_OK;
90 : }
91 :
92 : private:
93 : T* obj_;
94 : Method meth_;
95 : Params params_;
96 : };
97 :
98 : private:
99 : T* object_;
100 : };
101 :
102 : } // namespace ipc
103 : } // namespace mozilla
104 :
105 : #endif // mozilla_plugins_TaskFactory_h
|