X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fthird_party%2FWebKit%2FSource%2Fcore%2Fdom%2FCrossThreadTask.h;h=4bb24956f08fbbec1504a8a60713a5e8f0b7c631;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=d341205b62b4c311a2af6f81411058461cbfce2e;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/third_party/WebKit/Source/core/dom/CrossThreadTask.h b/src/third_party/WebKit/Source/core/dom/CrossThreadTask.h index d341205..4bb2495 100644 --- a/src/third_party/WebKit/Source/core/dom/CrossThreadTask.h +++ b/src/third_party/WebKit/Source/core/dom/CrossThreadTask.h @@ -38,7 +38,7 @@ #include "wtf/PassRefPtr.h" #include "wtf/TypeTraits.h" -namespace WebCore { +namespace blink { // Traits for the CrossThreadTask. template struct CrossThreadTaskTraits { @@ -57,8 +57,21 @@ template struct CrossThreadTaskTraits > { typedef PassOwnPtr ParamType; }; -// FIXME: Oilpan: Using a RawPtr is not safe. -// We need to move ExecutionContextTask to the heap and make this a Member. +// FIXME: Oilpan: Using a RawPtr is not safe, because the RawPtr does not keep +// the pointee alive while the ExecutionContextTask holds the RawPtr. +// +// - Ideally, we want to move the ExecutionContextTask to Oilpan's heap and use a Member. +// However we cannot do that easily because the ExecutionContextTask outlives the thread +// that created the ExecutionContextTask. Oilpan does not support objects that +// outlives the thread that created the objects. +// +// - It's not either easy to keep the ExecutionContextTask off-heap +// and use a Persistent handle. This is because the Persistent handle can cause a cycle. +// It's possible that the ExecutionContextTask holds a Persistent handle to the object +// that owns the ExecutionContextTask. +// +// Given the above, we cannot avoid using a RawPtr at the moment. +// It's a responsibility of the caller sites to manage the lifetime of the pointee. template struct CrossThreadTaskTraits > { typedef RawPtr ParamType; }; @@ -380,7 +393,7 @@ private: }; template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1), const P1& parameter1) { @@ -390,7 +403,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2), const P1& parameter1, const P2& parameter2) { @@ -400,7 +413,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2, MP3), const P1& parameter1, const P2& parameter2, const P3& parameter3) { @@ -411,7 +424,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4), const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) { @@ -423,7 +436,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5), const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) { @@ -436,7 +449,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6), const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6) { @@ -449,7 +462,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7), const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6, const P7& parameter7) { @@ -464,7 +477,7 @@ PassOwnPtr createCallbackTask( } template -PassOwnPtr createCallbackTask( +PassOwnPtr createCrossThreadTask( void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7, MP8), const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6, const P7& parameter7, const P8& parameter8) { @@ -478,6 +491,245 @@ PassOwnPtr createCallbackTask( CrossThreadCopier::copy(parameter7), CrossThreadCopier::copy(parameter8)); } -} // namespace WebCore +// 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&) 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 +PassOwnPtr createCrossThreadTask( + void (C::*function)(), + C* p) +{ + return CallClosureTask::create(bind(function, + p)); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1), + C* p, const P1& parameter1) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1))); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1, MP2), + C* p, const P1& parameter1, const P2& parameter2) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2))); +} + +template +PassOwnPtr 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::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3))); +} + +template +PassOwnPtr 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::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4))); +} + +template +PassOwnPtr 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::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4), + CrossThreadCopier::copy(parameter5))); +} + +// Templates for member function of class C + weak pointer (const WeakPtr&) +// which do not use CrossThreadCopier for the weak pointer (a1) +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(), + const WeakPtr& p) +{ + return CallClosureTask::create(bind(function, + p)); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1), + const WeakPtr& p, const P1& parameter1) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1))); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1, MP2), + const WeakPtr& p, const P1& parameter1, const P2& parameter2) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2))); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1, MP2, MP3), + const WeakPtr& p, const P1& parameter1, const P2& parameter2, const P3& parameter3) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3))); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1, MP2, MP3, MP4), + const WeakPtr& p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4))); +} + +template +PassOwnPtr createCrossThreadTask( + void (C::*function)(MP1, MP2, MP3, MP4, MP5), + const WeakPtr& p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) +{ + return CallClosureTask::create(bind(function, + p, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4), + CrossThreadCopier::copy(parameter5))); +} + +// Other cases; use CrossThreadCopier for all arguments +template +PassOwnPtr createCrossThreadTask( + FunctionType function) +{ + return CallClosureTask::create(bind(function)); +} + +template +PassOwnPtr createCrossThreadTask( + FunctionType function, + const P1& parameter1) +{ + return CallClosureTask::create(bind(function, + CrossThreadCopier::copy(parameter1))); +} + +template +PassOwnPtr createCrossThreadTask( + FunctionType function, + const P1& parameter1, const P2& parameter2) +{ + return CallClosureTask::create(bind(function, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2))); +} + +template +PassOwnPtr createCrossThreadTask( + FunctionType function, + const P1& parameter1, const P2& parameter2, const P3& parameter3) +{ + return CallClosureTask::create(bind(function, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3))); +} + +template +PassOwnPtr createCrossThreadTask( + FunctionType function, + const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) +{ + return CallClosureTask::create(bind(function, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4))); +} + +template +PassOwnPtr createCrossThreadTask( + FunctionType function, + const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) +{ + return CallClosureTask::create(bind(function, + CrossThreadCopier::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4), + CrossThreadCopier::copy(parameter5))); +} + +template +PassOwnPtr 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::copy(parameter1), + CrossThreadCopier::copy(parameter2), + CrossThreadCopier::copy(parameter3), + CrossThreadCopier::copy(parameter4), + CrossThreadCopier::copy(parameter5), + CrossThreadCopier::copy(parameter6))); +} + +} // namespace blink #endif // CrossThreadTask_h