Home | History | Annotate | Download | only in dom
      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