1/* 2 * Copyright (C) 2009-2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#ifndef CrossThreadTask_h 32#define CrossThreadTask_h 33 34#include "core/dom/ExecutionContext.h" 35#include "core/dom/ExecutionContextTask.h" 36#include "platform/CrossThreadCopier.h" 37#include "wtf/PassOwnPtr.h" 38#include "wtf/PassRefPtr.h" 39#include "wtf/TypeTraits.h" 40 41namespace blink { 42 43// Traits for the CrossThreadTask. 44template<typename T> struct CrossThreadTaskTraits { 45 typedef const T& ParamType; 46}; 47 48template<typename T> struct CrossThreadTaskTraits<T*> { 49 typedef T* ParamType; 50}; 51 52template<typename T> struct CrossThreadTaskTraits<PassRefPtr<T> > { 53 typedef PassRefPtr<T> ParamType; 54}; 55 56template<typename T> struct CrossThreadTaskTraits<PassOwnPtr<T> > { 57 typedef PassOwnPtr<T> ParamType; 58}; 59 60// FIXME: Oilpan: Using a RawPtr is not safe, because the RawPtr does not keep 61// the pointee alive while the ExecutionContextTask holds the RawPtr. 62// 63// - Ideally, we want to move the ExecutionContextTask to Oilpan's heap and use a Member. 64// However we cannot do that easily because the ExecutionContextTask outlives the thread 65// that created the ExecutionContextTask. Oilpan does not support objects that 66// outlives the thread that created the objects. 67// 68// - It's not either easy to keep the ExecutionContextTask off-heap 69// and use a Persistent handle. This is because the Persistent handle can cause a cycle. 70// It's possible that the ExecutionContextTask holds a Persistent handle to the object 71// that owns the ExecutionContextTask. 72// 73// Given the above, we cannot avoid using a RawPtr at the moment. 74// It's a responsibility of the caller sites to manage the lifetime of the pointee. 75template<typename T> struct CrossThreadTaskTraits<RawPtr<T> > { 76 typedef RawPtr<T> ParamType; 77}; 78 79template<typename P1, typename MP1> 80class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask1 : public ExecutionContextTask { 81public: 82 typedef void (*Method)(ExecutionContext*, MP1); 83 typedef CrossThreadTask1<P1, MP1> CrossThreadTask; 84 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 85 86 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1) 87 { 88 return adoptPtr(new CrossThreadTask(method, parameter1)); 89 } 90 91private: 92 CrossThreadTask1(Method method, Param1 parameter1) 93 : m_method(method) 94 , m_parameter1(parameter1) 95 { 96 } 97 98 virtual void performTask(ExecutionContext* context) 99 { 100 (*m_method)(context, m_parameter1); 101 } 102 103private: 104 Method m_method; 105 P1 m_parameter1; 106}; 107 108template<typename P1, typename MP1, typename P2, typename MP2> 109class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask2 : public ExecutionContextTask { 110public: 111 typedef void (*Method)(ExecutionContext*, MP1, MP2); 112 typedef CrossThreadTask2<P1, MP1, P2, MP2> CrossThreadTask; 113 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 114 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 115 116 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2) 117 { 118 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2)); 119 } 120 121private: 122 CrossThreadTask2(Method method, Param1 parameter1, Param2 parameter2) 123 : m_method(method) 124 , m_parameter1(parameter1) 125 , m_parameter2(parameter2) 126 { 127 } 128 129 virtual void performTask(ExecutionContext* context) 130 { 131 (*m_method)(context, m_parameter1, m_parameter2); 132 } 133 134private: 135 Method m_method; 136 P1 m_parameter1; 137 P2 m_parameter2; 138}; 139 140template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 141class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask3 : public ExecutionContextTask { 142public: 143 typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3); 144 typedef CrossThreadTask3<P1, MP1, P2, MP2, P3, MP3> CrossThreadTask; 145 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 146 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 147 typedef typename CrossThreadTaskTraits<P3>::ParamType Param3; 148 149 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3) 150 { 151 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2, parameter3)); 152 } 153 154private: 155 CrossThreadTask3(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3) 156 : m_method(method) 157 , m_parameter1(parameter1) 158 , m_parameter2(parameter2) 159 , m_parameter3(parameter3) 160 { 161 } 162 163 virtual void performTask(ExecutionContext* context) 164 { 165 (*m_method)(context, m_parameter1, m_parameter2, m_parameter3); 166 } 167 168private: 169 Method m_method; 170 P1 m_parameter1; 171 P2 m_parameter2; 172 P3 m_parameter3; 173}; 174 175template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 176class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask4 : public ExecutionContextTask { 177public: 178 typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4); 179 typedef CrossThreadTask4<P1, MP1, P2, MP2, P3, MP3, P4, MP4> CrossThreadTask; 180 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 181 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 182 typedef typename CrossThreadTaskTraits<P3>::ParamType Param3; 183 typedef typename CrossThreadTaskTraits<P4>::ParamType Param4; 184 185 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4) 186 { 187 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2, parameter3, parameter4)); 188 } 189 190private: 191 CrossThreadTask4(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4) 192 : m_method(method) 193 , m_parameter1(parameter1) 194 , m_parameter2(parameter2) 195 , m_parameter3(parameter3) 196 , m_parameter4(parameter4) 197 { 198 } 199 200 virtual void performTask(ExecutionContext* context) 201 { 202 (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4); 203 } 204 205private: 206 Method m_method; 207 P1 m_parameter1; 208 P2 m_parameter2; 209 P3 m_parameter3; 210 P4 m_parameter4; 211}; 212 213template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 214class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask5 : public ExecutionContextTask { 215public: 216 typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5); 217 typedef CrossThreadTask5<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5> CrossThreadTask; 218 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 219 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 220 typedef typename CrossThreadTaskTraits<P3>::ParamType Param3; 221 typedef typename CrossThreadTaskTraits<P4>::ParamType Param4; 222 typedef typename CrossThreadTaskTraits<P5>::ParamType Param5; 223 224 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5) 225 { 226 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2, parameter3, parameter4, parameter5)); 227 } 228 229private: 230 CrossThreadTask5(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5) 231 : m_method(method) 232 , m_parameter1(parameter1) 233 , m_parameter2(parameter2) 234 , m_parameter3(parameter3) 235 , m_parameter4(parameter4) 236 , m_parameter5(parameter5) 237 { 238 } 239 240 virtual void performTask(ExecutionContext* context) 241 { 242 (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5); 243 } 244 245private: 246 Method m_method; 247 P1 m_parameter1; 248 P2 m_parameter2; 249 P3 m_parameter3; 250 P4 m_parameter4; 251 P5 m_parameter5; 252}; 253 254template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6> 255class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask6 : public ExecutionContextTask { 256public: 257 typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6); 258 typedef CrossThreadTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> CrossThreadTask; 259 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 260 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 261 typedef typename CrossThreadTaskTraits<P3>::ParamType Param3; 262 typedef typename CrossThreadTaskTraits<P4>::ParamType Param4; 263 typedef typename CrossThreadTaskTraits<P5>::ParamType Param5; 264 typedef typename CrossThreadTaskTraits<P6>::ParamType Param6; 265 266 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6) 267 { 268 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6)); 269 } 270 271private: 272 CrossThreadTask6(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6) 273 : m_method(method) 274 , m_parameter1(parameter1) 275 , m_parameter2(parameter2) 276 , m_parameter3(parameter3) 277 , m_parameter4(parameter4) 278 , m_parameter5(parameter5) 279 , m_parameter6(parameter6) 280 { 281 } 282 283 virtual void performTask(ExecutionContext* context) 284 { 285 (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6); 286 } 287 288private: 289 Method m_method; 290 P1 m_parameter1; 291 P2 m_parameter2; 292 P3 m_parameter3; 293 P4 m_parameter4; 294 P5 m_parameter5; 295 P6 m_parameter6; 296}; 297 298template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7> 299class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask7 : public ExecutionContextTask { 300public: 301 typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7); 302 typedef CrossThreadTask7<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7> CrossThreadTask; 303 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 304 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 305 typedef typename CrossThreadTaskTraits<P3>::ParamType Param3; 306 typedef typename CrossThreadTaskTraits<P4>::ParamType Param4; 307 typedef typename CrossThreadTaskTraits<P5>::ParamType Param5; 308 typedef typename CrossThreadTaskTraits<P6>::ParamType Param6; 309 typedef typename CrossThreadTaskTraits<P7>::ParamType Param7; 310 311 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6, Param7 parameter7) 312 { 313 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6, parameter7)); 314 } 315 316private: 317 CrossThreadTask7(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6, Param7 parameter7) 318 : m_method(method) 319 , m_parameter1(parameter1) 320 , m_parameter2(parameter2) 321 , m_parameter3(parameter3) 322 , m_parameter4(parameter4) 323 , m_parameter5(parameter5) 324 , m_parameter6(parameter6) 325 , m_parameter7(parameter7) 326 { 327 } 328 329 virtual void performTask(ExecutionContext* context) 330 { 331 (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6, m_parameter7); 332 } 333 334private: 335 Method m_method; 336 P1 m_parameter1; 337 P2 m_parameter2; 338 P3 m_parameter3; 339 P4 m_parameter4; 340 P5 m_parameter5; 341 P6 m_parameter6; 342 P7 m_parameter7; 343}; 344 345template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7, typename P8, typename MP8> 346class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask8 : public ExecutionContextTask { 347public: 348 typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7, MP8); 349 typedef CrossThreadTask8<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7, P8, MP8> CrossThreadTask; 350 typedef typename CrossThreadTaskTraits<P1>::ParamType Param1; 351 typedef typename CrossThreadTaskTraits<P2>::ParamType Param2; 352 typedef typename CrossThreadTaskTraits<P3>::ParamType Param3; 353 typedef typename CrossThreadTaskTraits<P4>::ParamType Param4; 354 typedef typename CrossThreadTaskTraits<P5>::ParamType Param5; 355 typedef typename CrossThreadTaskTraits<P6>::ParamType Param6; 356 typedef typename CrossThreadTaskTraits<P7>::ParamType Param7; 357 typedef typename CrossThreadTaskTraits<P8>::ParamType Param8; 358 359 static PassOwnPtr<CrossThreadTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6, Param7 parameter7, Param8 parameter8) 360 { 361 return adoptPtr(new CrossThreadTask(method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6, parameter7, parameter8)); 362 } 363 364private: 365 CrossThreadTask8(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6, Param7 parameter7, Param8 parameter8) 366 : m_method(method) 367 , m_parameter1(parameter1) 368 , m_parameter2(parameter2) 369 , m_parameter3(parameter3) 370 , m_parameter4(parameter4) 371 , m_parameter5(parameter5) 372 , m_parameter6(parameter6) 373 , m_parameter7(parameter7) 374 , m_parameter8(parameter8) 375 { 376 } 377 378 virtual void performTask(ExecutionContext* context) 379 { 380 (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6, m_parameter7, m_parameter8); 381 } 382 383private: 384 Method m_method; 385 P1 m_parameter1; 386 P2 m_parameter2; 387 P3 m_parameter3; 388 P4 m_parameter4; 389 P5 m_parameter5; 390 P6 m_parameter6; 391 P7 m_parameter7; 392 P8 m_parameter8; 393}; 394 395template<typename P1, typename MP1> 396PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 397 void (*method)(ExecutionContext*, MP1), 398 const P1& parameter1) 399{ 400 return CrossThreadTask1<typename CrossThreadCopier<P1>::Type, MP1>::create( 401 method, 402 CrossThreadCopier<P1>::copy(parameter1)); 403} 404 405template<typename P1, typename MP1, typename P2, typename MP2> 406PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 407 void (*method)(ExecutionContext*, MP1, MP2), 408 const P1& parameter1, const P2& parameter2) 409{ 410 return CrossThreadTask2<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2>::create( 411 method, 412 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2)); 413} 414 415template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 416PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 417 void (*method)(ExecutionContext*, MP1, MP2, MP3), 418 const P1& parameter1, const P2& parameter2, const P3& parameter3) 419{ 420 return CrossThreadTask3<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3>::create( 421 method, 422 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2), 423 CrossThreadCopier<P3>::copy(parameter3)); 424} 425 426template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 427PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 428 void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4), 429 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) 430{ 431 return CrossThreadTask4<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3, 432 typename CrossThreadCopier<P4>::Type, MP4>::create( 433 method, 434 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2), 435 CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4)); 436} 437 438template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 439PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 440 void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5), 441 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) 442{ 443 return CrossThreadTask5<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3, 444 typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5>::create( 445 method, 446 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2), 447 CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4), 448 CrossThreadCopier<P5>::copy(parameter5)); 449} 450 451template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6> 452PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 453 void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6), 454 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6) 455{ 456 return CrossThreadTask6<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3, 457 typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5, typename CrossThreadCopier<P6>::Type, MP6>::create( 458 method, 459 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2), 460 CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4), 461 CrossThreadCopier<P5>::copy(parameter5), CrossThreadCopier<P6>::copy(parameter6)); 462} 463 464template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7> 465PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 466 void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7), 467 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6, const P7& parameter7) 468{ 469 return CrossThreadTask7<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3, 470 typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5, typename CrossThreadCopier<P6>::Type, MP6, 471 typename CrossThreadCopier<P7>::Type, MP7>::create( 472 method, 473 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2), 474 CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4), 475 CrossThreadCopier<P5>::copy(parameter5), CrossThreadCopier<P6>::copy(parameter6), 476 CrossThreadCopier<P7>::copy(parameter7)); 477} 478 479template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7, typename P8, typename MP8> 480PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 481 void (*method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7, MP8), 482 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6, const P7& parameter7, const P8& parameter8) 483{ 484 return CrossThreadTask8<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3, 485 typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5, typename CrossThreadCopier<P6>::Type, MP6, 486 typename CrossThreadCopier<P7>::Type, MP7, typename CrossThreadCopier<P8>::Type, MP8>::create( 487 method, 488 CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2), 489 CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4), 490 CrossThreadCopier<P5>::copy(parameter5), CrossThreadCopier<P6>::copy(parameter6), 491 CrossThreadCopier<P7>::copy(parameter7), CrossThreadCopier<P8>::copy(parameter8)); 492} 493 494// createCrossThreadTask(...) is similar to but safer than 495// CallClosureTask::create(bind(...)) for cross-thread task posting. 496// postTask(CallClosureTask::create(bind(...))) is not thread-safe 497// due to temporary objects, see http://crbug.com/390851 for details. 498// 499// createCrossThreadTask copies its arguments into Closure 500// by CrossThreadCopier, rather than copy constructors. 501// This means it creates deep copy of each argument if necessary. 502// 503// To pass things that cannot be copied by CrossThreadCopier 504// (e.g. pointers), use AllowCrossThreadAccess() explicitly. 505// 506// If the first argument of createCrossThreadTask 507// is a pointer to a member function in class C, 508// then the second argument of createCrossThreadTask 509// is a raw pointer (C*) or a weak pointer (const WeakPtr<C>&) to C. 510// createCrossThreadTask does not use CrossThreadCopier for the pointer, 511// assuming the user of createCrossThreadTask knows that the pointer 512// can be accessed from the target thread. 513 514// Templates for member function of class C + raw pointer (C*) 515// which do not use CrossThreadCopier for the raw pointer (a1) 516template<typename C> 517PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 518 void (C::*function)(), 519 C* p) 520{ 521 return CallClosureTask::create(bind(function, 522 p)); 523} 524 525template<typename C, typename P1, typename MP1> 526PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 527 void (C::*function)(MP1), 528 C* p, const P1& parameter1) 529{ 530 return CallClosureTask::create(bind(function, 531 p, 532 CrossThreadCopier<P1>::copy(parameter1))); 533} 534 535template<typename C, typename P1, typename MP1, typename P2, typename MP2> 536PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 537 void (C::*function)(MP1, MP2), 538 C* p, const P1& parameter1, const P2& parameter2) 539{ 540 return CallClosureTask::create(bind(function, 541 p, 542 CrossThreadCopier<P1>::copy(parameter1), 543 CrossThreadCopier<P2>::copy(parameter2))); 544} 545 546template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 547PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 548 void (C::*function)(MP1, MP2, MP3), 549 C* p, const P1& parameter1, const P2& parameter2, const P3& parameter3) 550{ 551 return CallClosureTask::create(bind(function, 552 p, 553 CrossThreadCopier<P1>::copy(parameter1), 554 CrossThreadCopier<P2>::copy(parameter2), 555 CrossThreadCopier<P3>::copy(parameter3))); 556} 557 558template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 559PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 560 void (C::*function)(MP1, MP2, MP3, MP4), 561 C* p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) 562{ 563 return CallClosureTask::create(bind(function, 564 p, 565 CrossThreadCopier<P1>::copy(parameter1), 566 CrossThreadCopier<P2>::copy(parameter2), 567 CrossThreadCopier<P3>::copy(parameter3), 568 CrossThreadCopier<P4>::copy(parameter4))); 569} 570 571template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 572PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 573 void (C::*function)(MP1, MP2, MP3, MP4, MP5), 574 C* p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) 575{ 576 return CallClosureTask::create(bind(function, 577 p, 578 CrossThreadCopier<P1>::copy(parameter1), 579 CrossThreadCopier<P2>::copy(parameter2), 580 CrossThreadCopier<P3>::copy(parameter3), 581 CrossThreadCopier<P4>::copy(parameter4), 582 CrossThreadCopier<P5>::copy(parameter5))); 583} 584 585// Templates for member function of class C + weak pointer (const WeakPtr<C>&) 586// which do not use CrossThreadCopier for the weak pointer (a1) 587template<typename C> 588PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 589 void (C::*function)(), 590 const WeakPtr<C>& p) 591{ 592 return CallClosureTask::create(bind(function, 593 p)); 594} 595 596template<typename C, typename P1, typename MP1> 597PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 598 void (C::*function)(MP1), 599 const WeakPtr<C>& p, const P1& parameter1) 600{ 601 return CallClosureTask::create(bind(function, 602 p, 603 CrossThreadCopier<P1>::copy(parameter1))); 604} 605 606template<typename C, typename P1, typename MP1, typename P2, typename MP2> 607PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 608 void (C::*function)(MP1, MP2), 609 const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2) 610{ 611 return CallClosureTask::create(bind(function, 612 p, 613 CrossThreadCopier<P1>::copy(parameter1), 614 CrossThreadCopier<P2>::copy(parameter2))); 615} 616 617template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 618PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 619 void (C::*function)(MP1, MP2, MP3), 620 const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2, const P3& parameter3) 621{ 622 return CallClosureTask::create(bind(function, 623 p, 624 CrossThreadCopier<P1>::copy(parameter1), 625 CrossThreadCopier<P2>::copy(parameter2), 626 CrossThreadCopier<P3>::copy(parameter3))); 627} 628 629template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 630PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 631 void (C::*function)(MP1, MP2, MP3, MP4), 632 const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) 633{ 634 return CallClosureTask::create(bind(function, 635 p, 636 CrossThreadCopier<P1>::copy(parameter1), 637 CrossThreadCopier<P2>::copy(parameter2), 638 CrossThreadCopier<P3>::copy(parameter3), 639 CrossThreadCopier<P4>::copy(parameter4))); 640} 641 642template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 643PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 644 void (C::*function)(MP1, MP2, MP3, MP4, MP5), 645 const WeakPtr<C>& p, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) 646{ 647 return CallClosureTask::create(bind(function, 648 p, 649 CrossThreadCopier<P1>::copy(parameter1), 650 CrossThreadCopier<P2>::copy(parameter2), 651 CrossThreadCopier<P3>::copy(parameter3), 652 CrossThreadCopier<P4>::copy(parameter4), 653 CrossThreadCopier<P5>::copy(parameter5))); 654} 655 656// Other cases; use CrossThreadCopier for all arguments 657template<typename FunctionType> 658PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 659 FunctionType function) 660{ 661 return CallClosureTask::create(bind(function)); 662} 663 664template<typename FunctionType, typename P1> 665PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 666 FunctionType function, 667 const P1& parameter1) 668{ 669 return CallClosureTask::create(bind(function, 670 CrossThreadCopier<P1>::copy(parameter1))); 671} 672 673template<typename FunctionType, typename P1, typename P2> 674PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 675 FunctionType function, 676 const P1& parameter1, const P2& parameter2) 677{ 678 return CallClosureTask::create(bind(function, 679 CrossThreadCopier<P1>::copy(parameter1), 680 CrossThreadCopier<P2>::copy(parameter2))); 681} 682 683template<typename FunctionType, typename P1, typename P2, typename P3> 684PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 685 FunctionType function, 686 const P1& parameter1, const P2& parameter2, const P3& parameter3) 687{ 688 return CallClosureTask::create(bind(function, 689 CrossThreadCopier<P1>::copy(parameter1), 690 CrossThreadCopier<P2>::copy(parameter2), 691 CrossThreadCopier<P3>::copy(parameter3))); 692} 693 694template<typename FunctionType, typename P1, typename P2, typename P3, typename P4> 695PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 696 FunctionType function, 697 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4) 698{ 699 return CallClosureTask::create(bind(function, 700 CrossThreadCopier<P1>::copy(parameter1), 701 CrossThreadCopier<P2>::copy(parameter2), 702 CrossThreadCopier<P3>::copy(parameter3), 703 CrossThreadCopier<P4>::copy(parameter4))); 704} 705 706template<typename FunctionType, typename P1, typename P2, typename P3, typename P4, typename P5> 707PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 708 FunctionType function, 709 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5) 710{ 711 return CallClosureTask::create(bind(function, 712 CrossThreadCopier<P1>::copy(parameter1), 713 CrossThreadCopier<P2>::copy(parameter2), 714 CrossThreadCopier<P3>::copy(parameter3), 715 CrossThreadCopier<P4>::copy(parameter4), 716 CrossThreadCopier<P5>::copy(parameter5))); 717} 718 719template<typename FunctionType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> 720PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 721 FunctionType function, 722 const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6) 723{ 724 return CallClosureTask::create(bind(function, 725 CrossThreadCopier<P1>::copy(parameter1), 726 CrossThreadCopier<P2>::copy(parameter2), 727 CrossThreadCopier<P3>::copy(parameter3), 728 CrossThreadCopier<P4>::copy(parameter4), 729 CrossThreadCopier<P5>::copy(parameter5), 730 CrossThreadCopier<P6>::copy(parameter6))); 731} 732 733} // namespace blink 734 735#endif // CrossThreadTask_h 736