Index: Source/core/dom/CrossThreadTask.h |
diff --git a/Source/core/dom/CrossThreadTask.h b/Source/core/dom/CrossThreadTask.h |
index d341205b62b4c311a2af6f81411058461cbfce2e..65b2da0e5f7956e0660293ad4d3d1ff4ad7dbf2e 100644 |
--- a/Source/core/dom/CrossThreadTask.h |
+++ b/Source/core/dom/CrossThreadTask.h |
@@ -478,6 +478,245 @@ 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* p) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p)); |
+} |
+ |
+template<typename C, typename P1, typename MP1> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1), |
+ C* p, const P1& parameter1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2), |
+ C* p, const P1& parameter1, const P2& parameter2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2, MP3), |
+ C* p, const P1& parameter1, const P2& parameter2, const P3& parameter3) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2, MP3, MP4), |
+ C* p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2, MP3, MP4, MP5), |
+ C* p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4), |
+ CrossThreadCopier<P5>::copy(parameter5))); |
+} |
+ |
+// 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>& p) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p)); |
+} |
+ |
+template<typename C, typename P1, typename MP1> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1), |
+ const WeakPtr<C>& p, const P1& parameter1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2), |
+ const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2, MP3), |
+ const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2, const P3& parameter3) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2, MP3, MP4), |
+ const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4))); |
+} |
+ |
+template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ void (C::*function)(MP1, MP2, MP3, MP4, MP5), |
+ const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ p, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4), |
+ CrossThreadCopier<P5>::copy(parameter5))); |
+} |
+ |
+// Other cases; use CrossThreadCopier for all arguments |
+template<typename FunctionType> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function) |
+{ |
+ return CallClosureTask::create(bind(function)); |
+} |
+ |
+template<typename FunctionType, typename P1> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function, |
+ const P1& parameter1) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<P1>::copy(parameter1))); |
+} |
+ |
+template<typename FunctionType, typename P1, typename P2> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function, |
+ const P1& parameter1, const P2& parameter2) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2))); |
+} |
+ |
+template<typename FunctionType, typename P1, typename P2, typename P3> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function, |
+ const P1& parameter1, const P2& parameter2, const P3& parameter3) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3))); |
+} |
+ |
+template<typename FunctionType, typename P1, typename P2, typename P3, typename P4> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function, |
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4))); |
+} |
+ |
+template<typename FunctionType, typename P1, typename P2, typename P3, typename P4, typename P5> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function, |
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4), |
+ CrossThreadCopier<P5>::copy(parameter5))); |
+} |
+ |
+template<typename FunctionType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> |
+PassOwnPtr<ExecutionContextTask> createCrossThreadTask( |
+ FunctionType function, |
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6) |
+{ |
+ return CallClosureTask::create(bind(function, |
+ CrossThreadCopier<P1>::copy(parameter1), |
+ CrossThreadCopier<P2>::copy(parameter2), |
+ CrossThreadCopier<P3>::copy(parameter3), |
+ CrossThreadCopier<P4>::copy(parameter4), |
+ CrossThreadCopier<P5>::copy(parameter5), |
+ CrossThreadCopier<P6>::copy(parameter6))); |
+} |
+ |
} // namespace WebCore |
#endif // CrossThreadTask_h |