Index: Source/core/dom/CrossThreadTask.h |
diff --git a/Source/core/dom/CrossThreadTask.h b/Source/core/dom/CrossThreadTask.h |
index d341205b62b4c311a2af6f81411058461cbfce2e..21c6526599b12f560fa9f52efd519c8ba27f3936 100644 |
--- a/Source/core/dom/CrossThreadTask.h |
+++ b/Source/core/dom/CrossThreadTask.h |
@@ -478,6 +478,208 @@ PassOwnPtr<ExecutionContextTask> createCallbackTask( |
CrossThreadCopier<P7>::copy(parameter7), CrossThreadCopier<P8>::copy(parameter8)); |
} |
+// createCrossThreadTask(...) is similar to but safer than |
+// CallClosureTask::create(bind(...)) for cross-thread task posting. |
+// postTask(CallClosureTask::create(bind(...))) is not thread-safe |
+// due to temporary objects, see http://crbug.com/390851 for details. |
+// |
+// createCrossThreadTask copies its arguments into Closure |
+// by CrossThreadCopier, rather than copy constructors. |
+// This means it creates deep copy of each argument if necessary. |
+// |
+// To pass things that cannot be copied by CrossThreadCopier |
+// (e.g. pointers), use AllowCrossThreadAccess() explicitly. |
+// |
+// If the first argument of createCrossThreadTask |
+// is a pointer to a member function in class C, |
+// then the second argument of createCrossThreadTask |
+// is a raw pointer (C*) or a weak pointer (const WeakPtr<C>&) to C. |
+// createCrossThreadTask does not use CrossThreadCopier for the pointer, |
+// assuming the user of createCrossThreadTask knows that the pointer |
+// can be accessed from the target thread. |
+ |
+// Templates for member function of class C + raw pointer (C*) |
+// which do not use CrossThreadCopier for the raw pointer (a1) |
+template<typename C> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(), C* a1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1)); |
+} |
+ |
+template<typename C, typename P2, typename A2> |
tyoshino (SeeGerritForStatus)
2014/07/10 07:31:46
Start from P1 and A1? We could also align with the
hiroshige
2014/07/10 08:14:35
Done.
|
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2), C* a1, const A2& a2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3), C* a1, const A2& a2, const A3& a3) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3, P4), C* a1, const A2& a2, const A3& a3, const A4& a4) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3, P4, P5), C* a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4), |
+ CrossThreadCopier<A5>::copy(a5))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5, typename P6, typename A6> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3, P4, P5, P6), C* a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4), |
+ CrossThreadCopier<A5>::copy(a5), |
+ CrossThreadCopier<A6>::copy(a6))); |
+} |
+ |
+// Templates for member function of class C + weak pointer (const WeakPtr<C>&) |
+// which do not use CrossThreadCopier for the weak pointer (a1) |
+template<typename C> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(), const WeakPtr<C>& a1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1)); |
+} |
+ |
+template<typename C, typename P2, typename A2> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2), const WeakPtr<C>& a1, const A2& a2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3), const WeakPtr<C>& a1, const A2& a2, const A3& a3) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3, P4), const WeakPtr<C>& a1, const A2& a2, const A3& a3, const A4& a4) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3, P4, P5), const WeakPtr<C>& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4), |
+ CrossThreadCopier<A5>::copy(a5))); |
+} |
+ |
+template<typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5, typename P6, typename A6> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(void (C::*function)(P2, P3, P4, P5, P6), const WeakPtr<C>& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4), |
+ CrossThreadCopier<A5>::copy(a5), |
+ CrossThreadCopier<A6>::copy(a6))); |
+} |
+ |
+// Other cases; use CrossThreadCopier for all arguments |
+template<typename FunctionType> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function) |
+{ |
+ return CallClosureTask::create(bind(function)); |
+} |
+ |
+template<typename FunctionType, typename A1> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function, const A1& a1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1))); |
+} |
+ |
+template<typename FunctionType, typename A1, typename A2> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function, const A1& a1, const A2& a2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1), |
+ CrossThreadCopier<A2>::copy(a2))); |
+} |
+ |
+template<typename FunctionType, typename A1, typename A2, typename A3> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function, const A1& a1, const A2& a2, const A3& a3) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1), |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3))); |
+} |
+ |
+template<typename FunctionType, typename A1, typename A2, typename A3, typename A4> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1), |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4))); |
+} |
+ |
+template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1), |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4), |
+ CrossThreadCopier<A5>::copy(a5))); |
+} |
+ |
+template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1), |
+ CrossThreadCopier<A2>::copy(a2), |
+ CrossThreadCopier<A3>::copy(a3), |
+ CrossThreadCopier<A4>::copy(a4), |
+ CrossThreadCopier<A5>::copy(a5), |
+ CrossThreadCopier<A6>::copy(a6))); |
+} |
+ |
} // namespace WebCore |
#endif // CrossThreadTask_h |