Chromium Code Reviews| 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 |