OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
dmichael (off chromium)
2013/01/15 22:43:52
nit: 2013 for new files
yzshen1
2013/01/16 18:55:59
Done. How time flies! :)
| |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_ | |
6 #define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_ | |
7 | |
8 #include "base/basictypes.h" | |
9 #include "base/bind.h" | |
10 #include "base/memory/ref_counted.h" | |
11 #include "ppapi/shared_impl/ppapi_shared_export.h" | |
12 #include "ppapi/shared_impl/proxy_lock.h" | |
13 | |
14 namespace ppapi { | |
15 | |
16 class MessageLoopShared; | |
17 | |
18 namespace internal { | |
19 | |
20 class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase { | |
21 protected: | |
22 ThreadAwareCallbackBase(); | |
23 ~ThreadAwareCallbackBase(); | |
24 | |
25 bool ShouldPostToTargetLoop(); | |
26 void RunIfNotAborted(const base::Closure& closure); | |
27 | |
28 private: | |
29 class Core; | |
30 | |
31 scoped_refptr<MessageLoopShared> target_loop_; | |
32 scoped_refptr<Core> core_; | |
33 | |
34 DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase); | |
35 }; | |
36 | |
37 } // namespace internal | |
38 | |
39 // Some PPB interfaces have methods that set a custom callback. Usually, the | |
40 // callback has to be called on the same thread as the one it was set on. | |
41 // ThreadAwareCallback keeps track of the target thread, and posts a task to run | |
42 // on it if requested from a different thread. | |
43 // | |
44 // Please note that: | |
45 // - Unlike TrackedCallback, there is not restriction of how many times the | |
dmichael (off chromium)
2013/01/15 22:43:52
nit: "not restriction of" -> "no restriction on"
yzshen1
2013/01/16 18:55:59
Done.
| |
46 // callback will be called. | |
47 // - When a ThreadAwareCallback object is destroyed, all pending tasks to run | |
48 // the callback will be ignored. It is designed this way so that when the | |
49 // resource is destroyed or the callback is cancelled by the plugin, we can | |
50 // simply delete the ThreadAwareCallback object to prevent touching the | |
51 // callback later. | |
52 template <class FuncType> | |
53 class ThreadAwareCallback; | |
dmichael (off chromium)
2013/01/15 22:43:52
It's worth noting that if called on the target thr
yzshen1
2013/01/16 18:55:59
Done. I added one more bullet point above.
On 201
| |
54 | |
55 template <> | |
56 class ThreadAwareCallback<void (*)()> | |
dmichael (off chromium)
2013/01/15 22:43:52
Do we really need all the specializations?
What a
yzshen1
2013/01/16 18:55:59
First, thanks a lot for writing the detailed comme
dmichael (off chromium)
2013/01/16 19:21:00
Bind is pretty cheap; I would worry more about rea
yzshen1
2013/01/16 22:37:36
I have made changes in the process of adding a Cre
| |
57 : public internal::ThreadAwareCallbackBase { | |
58 public: | |
59 typedef void (*FuncType)(); | |
60 | |
61 explicit ThreadAwareCallback(FuncType func) : func_(func) { | |
62 } | |
63 ~ThreadAwareCallback() { | |
64 } | |
65 | |
66 void RunOnTargetThread() { | |
67 if (ShouldPostToTargetLoop()) | |
68 RunIfNotAborted(base::Bind(func_)); | |
69 else | |
70 ppapi::CallWhileUnlocked<void>(func_); | |
dmichael (off chromium)
2013/01/15 22:43:52
You shouldn't need to pass a template parameter; i
yzshen1
2013/01/16 18:55:59
For this one, it is probably okay. But for those w
dmichael (off chromium)
2013/01/16 19:21:00
Ah, I see. Presumably it fails for const-ref argum
yzshen1
2013/01/16 22:37:36
I think so, haven't looked careful enough to find
| |
71 } | |
72 | |
73 private: | |
74 FuncType func_; | |
75 }; | |
76 | |
77 template <class P1> | |
78 class ThreadAwareCallback<void (*)(P1)> | |
79 : public internal::ThreadAwareCallbackBase { | |
80 public: | |
81 typedef void (*FuncType)(P1); | |
82 | |
83 explicit ThreadAwareCallback(FuncType func) : func_(func) { | |
84 } | |
85 ~ThreadAwareCallback() { | |
86 } | |
87 | |
88 void RunOnTargetThread(const P1& p1) { | |
89 if (ShouldPostToTargetLoop()) | |
90 RunIfNotAborted(base::Bind(func_, p1)); | |
91 else | |
92 ppapi::CallWhileUnlocked<void, P1>(func_, p1); | |
93 } | |
94 | |
95 private: | |
96 FuncType func_; | |
97 }; | |
98 | |
99 template <class P1, class P2> | |
100 class ThreadAwareCallback<void (*)(P1, P2)> | |
101 : public internal::ThreadAwareCallbackBase { | |
102 public: | |
103 typedef void (*FuncType)(P1, P2); | |
104 | |
105 explicit ThreadAwareCallback(FuncType func) : func_(func) { | |
106 } | |
107 ~ThreadAwareCallback() { | |
108 } | |
109 | |
110 void RunOnTargetThread(const P1& p1, const P2& p2) { | |
111 if (ShouldPostToTargetLoop()) | |
112 RunIfNotAborted(base::Bind(func_, p1, p2)); | |
113 else | |
114 ppapi::CallWhileUnlocked<void, P1, P2>(func_, p1, p2); | |
115 } | |
116 | |
117 private: | |
118 FuncType func_; | |
119 }; | |
120 | |
121 template <class P1, class P2, class P3> | |
122 class ThreadAwareCallback<void (*)(P1, P2, P3)> | |
123 : public internal::ThreadAwareCallbackBase { | |
124 public: | |
125 typedef void (*FuncType)(P1, P2, P3); | |
126 | |
127 explicit ThreadAwareCallback(FuncType func) : func_(func) { | |
128 } | |
129 ~ThreadAwareCallback() { | |
130 } | |
131 | |
132 void RunOnTargetThread(const P1& p1, const P2& p2, const P3& p3) { | |
133 if (ShouldPostToTargetLoop()) | |
134 RunIfNotAborted(base::Bind(func_, p1, p2, p3)); | |
135 else | |
136 ppapi::CallWhileUnlocked<void, P1, P2, P3>(func_, p1, p2, p3); | |
137 } | |
138 | |
139 private: | |
140 FuncType func_; | |
141 }; | |
142 | |
143 template <class P1, class P2, class P3, class P4> | |
144 class ThreadAwareCallback<void (*)(P1, P2, P3, P4)> | |
145 : public internal::ThreadAwareCallbackBase { | |
146 public: | |
147 typedef void (*FuncType)(P1, P2, P3, P4); | |
148 | |
149 explicit ThreadAwareCallback(FuncType func) : func_(func) { | |
150 } | |
151 ~ThreadAwareCallback() { | |
152 } | |
153 | |
154 void RunOnTargetThread(const P1& p1, | |
155 const P2& p2, | |
156 const P3& p3, | |
157 const P4& p4) { | |
158 if (ShouldPostToTargetLoop()) | |
159 RunIfNotAborted(base::Bind(func_, p1, p2, p3, p4)); | |
160 else | |
161 ppapi::CallWhileUnlocked<void, P1, P2, P3, P4>(func_, p1, p2, p3, p4); | |
162 } | |
163 | |
164 private: | |
165 FuncType func_; | |
166 }; | |
167 | |
168 template <class P1, class P2, class P3, class P4, class P5> | |
169 class ThreadAwareCallback<void (*)(P1, P2, P3, P4, P5)> | |
170 : public internal::ThreadAwareCallbackBase { | |
171 public: | |
172 typedef void (*FuncType)(P1, P2, P3, P4, P5); | |
173 | |
174 explicit ThreadAwareCallback(FuncType func) : func_(func) { | |
175 } | |
176 ~ThreadAwareCallback() { | |
177 } | |
178 | |
179 void RunOnTargetThread(const P1& p1, | |
180 const P2& p2, | |
181 const P3& p3, | |
182 const P4& p4, | |
183 const P5& p5) { | |
184 if (ShouldPostToTargetLoop()) { | |
185 RunIfNotAborted(base::Bind(func_, p1, p2, p3, p4, p5)); | |
186 } else { | |
187 ppapi::CallWhileUnlocked<void, P1, P2, P3, P4, P5>(func_, p1, p2, p3, p4, | |
188 p5); | |
189 } | |
190 } | |
191 | |
192 private: | |
193 FuncType func_; | |
194 }; | |
195 | |
196 } // namespace ppapi | |
197 | |
198 #endif // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_ | |
OLD | NEW |