| Index: third_party/WebKit/Source/core/dom/ExecutionContextTask.h
|
| diff --git a/third_party/WebKit/Source/core/dom/ExecutionContextTask.h b/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
|
| index 328d068caa5ff16f1c70adcd1dcf5a9d8fb678e4..15818c90bfd9e39301cd6d41e94fd744d30a1580 100644
|
| --- a/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
|
| +++ b/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
|
| @@ -28,11 +28,13 @@
|
| #define ExecutionContextTask_h
|
|
|
| #include "core/CoreExport.h"
|
| +#include "platform/CrossThreadFunctional.h"
|
| #include "wtf/Allocator.h"
|
| #include "wtf/Functional.h"
|
| #include "wtf/Noncopyable.h"
|
| #include "wtf/PtrUtil.h"
|
| #include "wtf/text/WTFString.h"
|
| +#include <type_traits>
|
|
|
| namespace blink {
|
|
|
| @@ -106,6 +108,56 @@ std::unique_ptr<ExecutionContextTask> createSameThreadTask(
|
| return internal::createCallClosureTask(WTF::bind(function, std::forward<P>(parameters)...));
|
| }
|
|
|
| +// createCrossThreadTask(...) is ExecutionContextTask version of
|
| +// crossThreadBind().
|
| +// Using WTF::bind() directly is not thread-safe due to temporary objects, see
|
| +// https://crbug.com/390851 for details.
|
| +//
|
| +// Example:
|
| +// void func1(int, const String&);
|
| +// createCrossThreadTask(func1, 42, str);
|
| +// func1(42, str2) will be called, where |str2| is a deep copy of
|
| +// |str| (created by str.isolatedCopy()).
|
| +//
|
| +// Don't (if you pass the task across threads):
|
| +// bind(func1, 42, str);
|
| +// bind(func1, 42, str.isolatedCopy());
|
| +//
|
| +// For functions:
|
| +// void functionEC(MP1, ..., MPn, ExecutionContext*);
|
| +// void function(MP1, ..., MPn);
|
| +// class C {
|
| +// void memberEC(MP1, ..., MPn, ExecutionContext*);
|
| +// void member(MP1, ..., MPn);
|
| +// };
|
| +// We create tasks represented by std::unique_ptr<ExecutionContextTask>:
|
| +// createCrossThreadTask(functionEC, const P1& p1, ..., const Pn& pn);
|
| +// createCrossThreadTask(memberEC, C* ptr, const P1& p1, ..., const Pn& pn);
|
| +// createCrossThreadTask(function, const P1& p1, ..., const Pn& pn);
|
| +// createCrossThreadTask(member, C* ptr, const P1& p1, ..., const Pn& pn);
|
| +// (|ptr| can also be WeakPtr<C> or other pointer-like types)
|
| +// and then the following are called on the target thread:
|
| +// functionEC(p1, ..., pn, context);
|
| +// ptr->memberEC(p1, ..., pn, context);
|
| +// function(p1, ..., pn);
|
| +// ptr->member(p1, ..., pn);
|
| +//
|
| +// ExecutionContext:
|
| +// |context| is supplied by the target thread.
|
| +//
|
| +// Deep copies by crossThreadBind():
|
| +// |ptr|, |p1|, ..., |pn| are processed by crossThreadBind() and thus
|
| +// CrossThreadCopier.
|
| +// You don't have to call manually e.g. isolatedCopy().
|
| +// To pass things that cannot be copied by CrossThreadCopier
|
| +// (e.g. pointers), use crossThreadUnretained() explicitly.
|
| +
|
| +template<typename FunctionType, typename... P>
|
| +std::unique_ptr<ExecutionContextTask> createCrossThreadTask(FunctionType function, P&&... parameters)
|
| +{
|
| + return internal::createCallClosureTask(crossThreadBind(function, std::forward<P>(parameters)...));
|
| +}
|
| +
|
| } // namespace blink
|
|
|
| #endif
|
|
|