Index: Source/core/dom/CrossThreadTask.h |
diff --git a/Source/core/dom/CrossThreadTask.h b/Source/core/dom/CrossThreadTask.h |
index d341205b62b4c311a2af6f81411058461cbfce2e..2b17447a282825062dcf9ab00c9550052e249692 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)); |
} |
+// createCallClosureTask(...) is similar to but safer than |
tkent
2014/07/10 03:36:14
I'd like to name this createCrossThreadTask.
This
hiroshige
2014/07/10 04:39:56
The name createCrossThreadTask seems good, but doe
tyoshino (SeeGerritForStatus)
2014/07/10 04:50:04
Yes we can also rename 1 later to align naming con
tkent
2014/07/10 05:06:23
I'm sorry, I meant createCallbackTask.
Smaller pa
hiroshige
2014/07/10 07:16:31
Probably yes.
I renamed createCallClosureTask to
|
+// 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. |
+// |
+// createCallClosureTask 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 createCallClosureTask |
+// is a pointer to a member function in class C, |
+// then the second argument of createCallClosureTask |
+// is a raw pointer (C*) or a weak pointer (const WeakPtr<C>&) to C. |
+// createCallClosureTask does not use CrossThreadCopier for the pointer, |
+// assuming the user of createCallClosureTask 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 R, typename C> |
tkent
2014/07/10 03:36:14
Is R necessary? it's always void, right?
hiroshige
2014/07/10 04:39:56
Right, because CallClosureTask::create require Clo
hiroshige
2014/07/10 07:16:32
Done.
|
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(), C* a1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1)); |
+} |
+ |
+template<typename R, typename C, typename P2, typename A2> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2), C* a1, const A2& a2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2))); |
+} |
+ |
+template<typename R, typename C, typename P2, typename A2, typename P3, typename A3> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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 R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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 R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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 R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5, typename P6, typename A6> |
+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, 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 R, typename C> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(), const WeakPtr<C>& a1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1)); |
+} |
+ |
+template<typename R, typename C, typename P2, typename A2> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*function)(P2), const WeakPtr<C>& a1, const A2& a2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ a1, |
+ CrossThreadCopier<A2>::copy(a2))); |
+} |
+ |
+template<typename R, typename C, typename P2, typename A2, typename P3, typename A3> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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 R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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 R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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 R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5, typename P6, typename A6> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (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> createCallClosureTask(FunctionType function) |
+{ |
+ return CallClosureTask::create(bind(function)); |
+} |
+ |
+template<typename FunctionType, typename A1> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType function, const A1& a1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<A1>::copy(a1))); |
+} |
+ |
+template<typename FunctionType, typename A1, typename A2> |
+PassOwnPtr<ExecutionContextTask> createCallClosureTask(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> createCallClosureTask(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> createCallClosureTask(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> createCallClosureTask(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> createCallClosureTask(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 |