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 41 namespace blink { 42 43 // Traits for the CrossThreadTask. 44 template<typename T> struct CrossThreadTaskTraits { 45 typedef const T& ParamType; 46 }; 47 48 template<typename T> struct CrossThreadTaskTraits<T*> { 49 typedef T* ParamType; 50 }; 51 52 template<typename T> struct CrossThreadTaskTraits<PassRefPtr<T> > { 53 typedef PassRefPtr<T> ParamType; 54 }; 55 56 template<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. 75 template<typename T> struct CrossThreadTaskTraits<RawPtr<T> > { 76 typedef RawPtr<T> ParamType; 77 }; 78 79 template<typename P1, typename MP1> 80 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask1 : public ExecutionContextTask { 81 public: 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 91 private: 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 103 private: 104 Method m_method; 105 P1 m_parameter1; 106 }; 107 108 template<typename P1, typename MP1, typename P2, typename MP2> 109 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask2 : public ExecutionContextTask { 110 public: 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 121 private: 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 134 private: 135 Method m_method; 136 P1 m_parameter1; 137 P2 m_parameter2; 138 }; 139 140 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 141 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask3 : public ExecutionContextTask { 142 public: 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 154 private: 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 168 private: 169 Method m_method; 170 P1 m_parameter1; 171 P2 m_parameter2; 172 P3 m_parameter3; 173 }; 174 175 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 176 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask4 : public ExecutionContextTask { 177 public: 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 190 private: 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 205 private: 206 Method m_method; 207 P1 m_parameter1; 208 P2 m_parameter2; 209 P3 m_parameter3; 210 P4 m_parameter4; 211 }; 212 213 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 214 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask5 : public ExecutionContextTask { 215 public: 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 229 private: 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 245 private: 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 254 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6> 255 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask6 : public ExecutionContextTask { 256 public: 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 271 private: 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 288 private: 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 298 template<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> 299 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask7 : public ExecutionContextTask { 300 public: 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 316 private: 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 334 private: 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 345 template<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> 346 class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask8 : public ExecutionContextTask { 347 public: 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 364 private: 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 383 private: 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 395 template<typename P1, typename MP1> 396 PassOwnPtr<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 405 template<typename P1, typename MP1, typename P2, typename MP2> 406 PassOwnPtr<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 415 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 416 PassOwnPtr<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 426 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 427 PassOwnPtr<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 438 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 439 PassOwnPtr<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 451 template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6> 452 PassOwnPtr<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 464 template<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> 465 PassOwnPtr<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 479 template<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> 480 PassOwnPtr<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) 516 template<typename C> 517 PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 518 void (C::*function)(), 519 C* p) 520 { 521 return CallClosureTask::create(bind(function, 522 p)); 523 } 524 525 template<typename C, typename P1, typename MP1> 526 PassOwnPtr<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 535 template<typename C, typename P1, typename MP1, typename P2, typename MP2> 536 PassOwnPtr<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 546 template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 547 PassOwnPtr<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 558 template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 559 PassOwnPtr<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 571 template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 572 PassOwnPtr<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) 587 template<typename C> 588 PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 589 void (C::*function)(), 590 const WeakPtr<C>& p) 591 { 592 return CallClosureTask::create(bind(function, 593 p)); 594 } 595 596 template<typename C, typename P1, typename MP1> 597 PassOwnPtr<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 606 template<typename C, typename P1, typename MP1, typename P2, typename MP2> 607 PassOwnPtr<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 617 template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3> 618 PassOwnPtr<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 629 template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4> 630 PassOwnPtr<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 642 template<typename C, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5> 643 PassOwnPtr<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 657 template<typename FunctionType> 658 PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 659 FunctionType function) 660 { 661 return CallClosureTask::create(bind(function)); 662 } 663 664 template<typename FunctionType, typename P1> 665 PassOwnPtr<ExecutionContextTask> createCrossThreadTask( 666 FunctionType function, 667 const P1& parameter1) 668 { 669 return CallClosureTask::create(bind(function, 670 CrossThreadCopier<P1>::copy(parameter1))); 671 } 672 673 template<typename FunctionType, typename P1, typename P2> 674 PassOwnPtr<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 683 template<typename FunctionType, typename P1, typename P2, typename P3> 684 PassOwnPtr<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 694 template<typename FunctionType, typename P1, typename P2, typename P3, typename P4> 695 PassOwnPtr<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 706 template<typename FunctionType, typename P1, typename P2, typename P3, typename P4, typename P5> 707 PassOwnPtr<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 719 template<typename FunctionType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> 720 PassOwnPtr<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