Index: Source/core/dom/ExecutionContextTask.h |
diff --git a/Source/core/dom/ExecutionContextTask.h b/Source/core/dom/ExecutionContextTask.h |
index dbc98d3b69b1666270a45899775ca0b41175a99b..95709efcc97e40a276254a905d75417faf41b4cd 100644 |
--- a/Source/core/dom/ExecutionContextTask.h |
+++ b/Source/core/dom/ExecutionContextTask.h |
@@ -27,10 +27,12 @@ |
#ifndef ExecutionContextTask_h |
#define ExecutionContextTask_h |
+#include "platform/CrossThreadCopier.h" |
#include "wtf/FastAllocBase.h" |
#include "wtf/Functional.h" |
#include "wtf/Noncopyable.h" |
#include "wtf/PassOwnPtr.h" |
+#include "wtf/WeakPtr.h" |
namespace WebCore { |
@@ -49,17 +51,266 @@ public: |
class CallClosureTask FINAL : public ExecutionContextTask { |
public: |
+ virtual void performTask(ExecutionContext*) OVERRIDE { m_closure(); } |
+ |
+private: |
+ // Do not use create other than in createCallClosureTask. http://crbug.com/390851 |
static PassOwnPtr<CallClosureTask> create(const Closure& closure) |
{ |
return adoptPtr(new CallClosureTask(closure)); |
} |
- virtual void performTask(ExecutionContext*) OVERRIDE { m_closure(); } |
- |
-private: |
explicit CallClosureTask(const Closure& closure) : m_closure(closure) { } |
Closure m_closure; |
+ |
+ // 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.
|
+ // 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.
|
+ template<typename R, typename C> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(), C*); |
+ template<typename R, typename C, typename P2, typename A2> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2), C*, const A2&); |
+ template<typename R, typename C, typename P2, typename A2, typename P3, typename A3> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3), C*, const A2&, const A3&); |
+ template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3, P4), C*, const A2&, const A3&, const A4&); |
+ template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3, P4, P5), C*, const A2&, const A3&, const A4&, const 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> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3, P4, P5, P6), C*, const A2&, const A3&, const A4&, const A5&, const A6&); |
+ // templates for member function of class C + weak pointer (const WeakPtr<C>&) |
+ // which do not use CrossThreadCopier for a1 |
+ template<typename R, typename C> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(), const WeakPtr<C>&); |
+ template<typename R, typename C, typename P2, typename A2> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2), const WeakPtr<C>&, const A2&); |
+ template<typename R, typename C, typename P2, typename A2, typename P3, typename A3> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3), const WeakPtr<C>&, const A2&, const A3&); |
+ template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3, P4), const WeakPtr<C>&, const A2&, const A3&, const A4&); |
+ template<typename R, typename C, typename P2, typename A2, typename P3, typename A3, typename P4, typename A4, typename P5, typename A5> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3, P4, P5), const WeakPtr<C>&, const A2&, const A3&, const A4&, const 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> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(R (C::*)(P2, P3, P4, P5, P6), const WeakPtr<C>&, const A2&, const A3&, const A4&, const A5&, const A6&); |
+ // other cases; use CrossThreadCopier for all arguments |
+ template<typename FunctionType> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType); |
+ template<typename FunctionType, typename A1> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&); |
+ template<typename FunctionType, typename A1, typename A2> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&); |
+ template<typename FunctionType, typename A1, typename A2, typename A3> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&); |
+ template<typename FunctionType, typename A1, typename A2, typename A3, typename A4> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&, const A4&); |
+ template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&, const A4&, const A5&); |
+ template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> |
+ friend PassOwnPtr<ExecutionContextTask> createCallClosureTask(FunctionType, const A1&, const A2&, const A3&, const A4&, const A5&, const A6&); |
}; |
+/* |
+createCallClosureTask(...) 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. |
+ |
+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. |
+*/ |
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.
|
+ |
+// templates for member function of class C + raw pointer (C*) |
+// which do not use CrossThreadCopier for a1 |
+template<typename R, typename C> |
+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 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 |
#endif |