OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Neither the name of Google Inc. nor the names of its | 10 * * Neither the name of Google Inc. nor the names of its |
11 * contributors may be used to endorse or promote products derived from | 11 * contributors may be used to endorse or promote products derived from |
12 * this software without specific prior written permission. | 12 * this software without specific prior written permission. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #ifndef ExecutionContextTask_h | 27 #ifndef ExecutionContextTask_h |
28 #define ExecutionContextTask_h | 28 #define ExecutionContextTask_h |
29 | 29 |
30 #include "platform/CrossThreadCopier.h" | |
30 #include "wtf/FastAllocBase.h" | 31 #include "wtf/FastAllocBase.h" |
31 #include "wtf/Functional.h" | 32 #include "wtf/Functional.h" |
32 #include "wtf/Noncopyable.h" | 33 #include "wtf/Noncopyable.h" |
33 #include "wtf/PassOwnPtr.h" | 34 #include "wtf/PassOwnPtr.h" |
35 #include "wtf/WeakPtr.h" | |
34 | 36 |
35 namespace WebCore { | 37 namespace WebCore { |
36 | 38 |
37 class ExecutionContext; | 39 class ExecutionContext; |
38 | 40 |
39 class ExecutionContextTask { | 41 class ExecutionContextTask { |
40 WTF_MAKE_NONCOPYABLE(ExecutionContextTask); | 42 WTF_MAKE_NONCOPYABLE(ExecutionContextTask); |
41 WTF_MAKE_FAST_ALLOCATED; | 43 WTF_MAKE_FAST_ALLOCATED; |
42 public: | 44 public: |
43 ExecutionContextTask() { } | 45 ExecutionContextTask() { } |
44 virtual ~ExecutionContextTask() { } | 46 virtual ~ExecutionContextTask() { } |
45 virtual void performTask(ExecutionContext*) = 0; | 47 virtual void performTask(ExecutionContext*) = 0; |
46 // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue. | 48 // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue. |
47 virtual bool isCleanupTask() const { return false; } | 49 virtual bool isCleanupTask() const { return false; } |
48 }; | 50 }; |
49 | 51 |
50 class CallClosureTask FINAL : public ExecutionContextTask { | 52 class CallClosureTask FINAL : public ExecutionContextTask { |
51 public: | 53 public: |
54 virtual void performTask(ExecutionContext*) OVERRIDE { m_closure(); } | |
55 | |
56 private: | |
57 // Do not use create other than in createCallClosureTask. http://crbug.com/3 90851 | |
52 static PassOwnPtr<CallClosureTask> create(const Closure& closure) | 58 static PassOwnPtr<CallClosureTask> create(const Closure& closure) |
53 { | 59 { |
54 return adoptPtr(new CallClosureTask(closure)); | 60 return adoptPtr(new CallClosureTask(closure)); |
55 } | 61 } |
56 virtual void performTask(ExecutionContext*) OVERRIDE { m_closure(); } | |
57 | |
58 private: | |
59 explicit CallClosureTask(const Closure& closure) : m_closure(closure) { } | 62 explicit CallClosureTask(const Closure& closure) : m_closure(closure) { } |
60 Closure m_closure; | 63 Closure m_closure; |
64 | |
65 // templates for member function of class C + raw pointer (C*) | |
tyoshino (SeeGerritForStatus)
2014/07/07 09:48:09
Start with a capital letter plz.
hiroshige
2014/07/07 11:31:27
Done.
| |
66 // which do not use CrossThreadCopier for a1 | |
tyoshino (SeeGerritForStatus)
2014/07/07 09:48:09
argument names are omitted here due to Blink codin
hiroshige
2014/07/07 11:31:26
Done.
| |
67 template<typename R, typename C> | |
68 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(), C* ); | |
69 template<typename R, typename C, typename P2, typename A2> | |
70 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2), C*, const A2&); | |
71 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3> | |
72 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3), C*, const A2&, const A3&); | |
73 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3, typename P4, typename A4> | |
74 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3, P4), C*, const A2&, const A3&, const A4&); | |
75 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3, typename P4, typename A4, typename P5, typename A5> | |
76 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3, P4, P5), C*, const A2&, const A3&, const A4&, const A5&); | |
77 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3, typename P4, typename A4, typename P5, typename A5, typename P6, typena me A6> | |
78 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3, P4, P5, P6), C*, const A2&, const A3&, const A4&, const A5&, const A6&); | |
79 // templates for member function of class C + weak pointer (const WeakPtr<C> &) | |
80 // which do not use CrossThreadCopier for a1 | |
81 template<typename R, typename C> | |
82 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(), co nst WeakPtr<C>&); | |
83 template<typename R, typename C, typename P2, typename A2> | |
84 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2), const WeakPtr<C>&, const A2&); | |
85 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3> | |
86 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3), const WeakPtr<C>&, const A2&, const A3&); | |
87 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3, typename P4, typename A4> | |
88 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3, P4), const WeakPtr<C>&, const A2&, const A3&, const A4&); | |
89 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3, typename P4, typename A4, typename P5, typename A5> | |
90 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3, P4, P5), const WeakPtr<C>&, const A2&, const A3&, const A4&, const A5&); | |
91 template<typename R, typename C, typename P2, typename A2, typename P3, type name A3, typename P4, typename A4, typename P5, typename A5, typename P6, typena me A6> | |
92 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P 3, P4, P5, P6), const WeakPtr<C>&, const A2&, const A3&, const A4&, const A5&, c onst A6&); | |
93 // other cases; use CrossThreadCopier for all arguments | |
94 template<typename FunctionType> | |
95 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType); | |
96 template<typename FunctionType, typename A1> | |
97 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&); | |
98 template<typename FunctionType, typename A1, typename A2> | |
99 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&); | |
100 template<typename FunctionType, typename A1, typename A2, typename A3> | |
101 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&); | |
102 template<typename FunctionType, typename A1, typename A2, typename A3, typen ame A4> | |
103 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&, const A4&); | |
104 template<typename FunctionType, typename A1, typename A2, typename A3, typen ame A4, typename A5> | |
105 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&, const A4&, const A5&); | |
106 template<typename FunctionType, typename A1, typename A2, typename A3, typen ame A4, typename A5, typename A6> | |
107 friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&, const A4&, const A5&, const A6&); | |
61 }; | 108 }; |
62 | 109 |
110 /* | |
111 createCallClosureTask(...) is similar to but safer than | |
112 CallClosureTask::create(bind(...)) for cross-thread task posting. | |
113 postTask(CallClosureTask::create(bind(...))) is not thread-safe | |
114 due to temporary objects, see http://crbug.com/390851 for details. | |
115 | |
116 createCallClosureTask copies its arguments into Closure | |
117 by CrossThreadCopier, rather than copy constructors. | |
118 This means it creates deep copy of each argument if necessary. | |
119 | |
120 To pass things that cannot be copied by CrossThreadCopier | |
121 (e.g. pointers), use AllowCrossThreadAccess() explicitly. | |
122 | |
123 If the first argument of createCallClosureTask | |
124 is a pointer to a member function in class C, | |
125 then the second argument of createCallClosureTask | |
126 is a raw pointer (C*) or a weak pointer (const WeakPtr<C>&) to C. | |
127 createCallClosureTask does not use CrossThreadCopier for the pointer, | |
128 assuming the user of createCallClosureTask knows that the pointer | |
129 can be accessed from the target thread. | |
130 */ | |
tyoshino (SeeGerritForStatus)
2014/07/07 09:48:09
except for copyright notice, it's more common to u
hiroshige
2014/07/07 11:31:26
Done.
| |
131 | |
132 // templates for member function of class C + raw pointer (C*) | |
133 // which do not use CrossThreadCopier for a1 | |
134 template<typename R, typename C> | |
135 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(), C* a1 ) | |
136 { | |
137 return CallClosureTask::create(bind(function, | |
138 a1)); | |
139 } | |
140 | |
141 template<typename R, typename C, typename P2, typename A2> | |
142 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2), C* a1, const A2& a2) | |
143 { | |
144 return CallClosureTask::create(bind(function, | |
145 a1, | |
146 CrossThreadCopier<A2>::copy(a2))); | |
147 } | |
148 | |
149 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3> | |
150 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3), C* a1, const A2& a2, const A3& a3) | |
151 { | |
152 return CallClosureTask::create(bind(function, | |
153 a1, | |
154 CrossThreadCopier<A2>::copy(a2), | |
155 CrossThreadCopier<A3>::copy(a3))); | |
156 } | |
157 | |
158 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> | |
159 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3, P4), C* a1, const A2& a2, const A3& a3, const A4& a4) | |
160 { | |
161 return CallClosureTask::create(bind(function, | |
162 a1, | |
163 CrossThreadCopier<A2>::copy(a2), | |
164 CrossThreadCopier<A3>::copy(a3), | |
165 CrossThreadCopier<A4>::copy(a4))); | |
166 } | |
167 | |
168 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> | |
169 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3, P4, P5), C* a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) | |
170 { | |
171 return CallClosureTask::create(bind(function, | |
172 a1, | |
173 CrossThreadCopier<A2>::copy(a2), | |
174 CrossThreadCopier<A3>::copy(a3), | |
175 CrossThreadCopier<A4>::copy(a4), | |
176 CrossThreadCopier<A5>::copy(a5))); | |
177 } | |
178 | |
179 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5, typename P6, typename A 6> | |
180 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3, P4, P5, P6), C* a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, cons t A6& a6) | |
181 { | |
182 return CallClosureTask::create(bind(function, | |
183 a1, | |
184 CrossThreadCopier<A2>::copy(a2), | |
185 CrossThreadCopier<A3>::copy(a3), | |
186 CrossThreadCopier<A4>::copy(a4), | |
187 CrossThreadCopier<A5>::copy(a5), | |
188 CrossThreadCopier<A6>::copy(a6))); | |
189 } | |
190 | |
191 // templates for member function of class C + weak pointer (const WeakPtr<C>&) | |
192 // which do not use CrossThreadCopier for a1 | |
193 template<typename R, typename C> | |
194 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(), const WeakPtr<C>& a1) | |
195 { | |
196 return CallClosureTask::create(bind(function, | |
197 a1)); | |
198 } | |
199 | |
200 template<typename R, typename C, typename P2, typename A2> | |
201 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2), con st WeakPtr<C>& a1, const A2& a2) | |
202 { | |
203 return CallClosureTask::create(bind(function, | |
204 a1, | |
205 CrossThreadCopier<A2>::copy(a2))); | |
206 } | |
207 | |
208 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3> | |
209 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3), const WeakPtr<C>& a1, const A2& a2, const A3& a3) | |
210 { | |
211 return CallClosureTask::create(bind(function, | |
212 a1, | |
213 CrossThreadCopier<A2>::copy(a2), | |
214 CrossThreadCopier<A3>::copy(a3))); | |
215 } | |
216 | |
217 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> | |
218 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3, P4), const WeakPtr<C>& a1, const A2& a2, const A3& a3, const A4& a4) | |
219 { | |
220 return CallClosureTask::create(bind(function, | |
221 a1, | |
222 CrossThreadCopier<A2>::copy(a2), | |
223 CrossThreadCopier<A3>::copy(a3), | |
224 CrossThreadCopier<A4>::copy(a4))); | |
225 } | |
226 | |
227 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> | |
228 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3, P4, P5), const WeakPtr<C>& a1, const A2& a2, const A3& a3, const A4& a4, const A 5& a5) | |
229 { | |
230 return CallClosureTask::create(bind(function, | |
231 a1, | |
232 CrossThreadCopier<A2>::copy(a2), | |
233 CrossThreadCopier<A3>::copy(a3), | |
234 CrossThreadCopier<A4>::copy(a4), | |
235 CrossThreadCopier<A5>::copy(a5))); | |
236 } | |
237 | |
238 template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5, typename P6, typename A 6> | |
239 PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2, P3, P4, P5, P6), const WeakPtr<C>& a1, const A2& a2, const A3& a3, const A4& a4, con st A5& a5, const A6& a6) | |
240 { | |
241 return CallClosureTask::create(bind(function, | |
242 a1, | |
243 CrossThreadCopier<A2>::copy(a2), | |
244 CrossThreadCopier<A3>::copy(a3), | |
245 CrossThreadCopier<A4>::copy(a4), | |
246 CrossThreadCopier<A5>::copy(a5), | |
247 CrossThreadCopier<A6>::copy(a6))); | |
248 } | |
249 | |
250 // other cases; use CrossThreadCopier for all arguments | |
251 template<typename FunctionType> | |
252 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function) | |
253 { | |
254 return CallClosureTask::create(bind(function)); | |
255 } | |
256 | |
257 template<typename FunctionType, typename A1> | |
258 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, co nst A1& a1) | |
259 { | |
260 return CallClosureTask::create(bind(function, | |
261 CrossThreadCopier<A1>::copy(a1))); | |
262 } | |
263 | |
264 template<typename FunctionType, typename A1, typename A2> | |
265 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, co nst A1& a1, const A2& a2) | |
266 { | |
267 return CallClosureTask::create(bind(function, | |
268 CrossThreadCopier<A1>::copy(a1), | |
269 CrossThreadCopier<A2>::copy(a2))); | |
270 } | |
271 | |
272 template<typename FunctionType, typename A1, typename A2, typename A3> | |
273 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, co nst A1& a1, const A2& a2, const A3& a3) | |
274 { | |
275 return CallClosureTask::create(bind(function, | |
276 CrossThreadCopier<A1>::copy(a1), | |
277 CrossThreadCopier<A2>::copy(a2), | |
278 CrossThreadCopier<A3>::copy(a3))); | |
279 } | |
280 | |
281 template<typename FunctionType, typename A1, typename A2, typename A3, typename A4> | |
282 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, co nst A1& a1, const A2& a2, const A3& a3, const A4& a4) | |
283 { | |
284 return CallClosureTask::create(bind(function, | |
285 CrossThreadCopier<A1>::copy(a1), | |
286 CrossThreadCopier<A2>::copy(a2), | |
287 CrossThreadCopier<A3>::copy(a3), | |
288 CrossThreadCopier<A4>::copy(a4))); | |
289 } | |
290 | |
291 template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5> | |
292 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, co nst A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) | |
293 { | |
294 return CallClosureTask::create(bind(function, | |
295 CrossThreadCopier<A1>::copy(a1), | |
296 CrossThreadCopier<A2>::copy(a2), | |
297 CrossThreadCopier<A3>::copy(a3), | |
298 CrossThreadCopier<A4>::copy(a4), | |
299 CrossThreadCopier<A5>::copy(a5))); | |
300 } | |
301 | |
302 template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> | |
303 PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, co nst A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6 ) | |
304 { | |
305 return CallClosureTask::create(bind(function, | |
306 CrossThreadCopier<A1>::copy(a1), | |
307 CrossThreadCopier<A2>::copy(a2), | |
308 CrossThreadCopier<A3>::copy(a3), | |
309 CrossThreadCopier<A4>::copy(a4), | |
310 CrossThreadCopier<A5>::copy(a5), | |
311 CrossThreadCopier<A6>::copy(a6))); | |
312 } | |
313 | |
63 } // namespace | 314 } // namespace |
64 | 315 |
65 #endif | 316 #endif |
OLD | NEW |