Home | History | Annotate | Download | only in platform
      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 CrossThreadCopier_h
     32 #define CrossThreadCopier_h
     33 
     34 #include "platform/PlatformExport.h"
     35 #include "platform/heap/Handle.h"
     36 #include "wtf/Assertions.h"
     37 #include "wtf/Forward.h"
     38 #include "wtf/PassOwnPtr.h"
     39 #include "wtf/PassRefPtr.h"
     40 #include "wtf/RawPtr.h"
     41 #include "wtf/RefPtr.h"
     42 #include "wtf/ThreadSafeRefCounted.h"
     43 #include "wtf/TypeTraits.h"
     44 
     45 namespace blink {
     46 
     47     class IntRect;
     48     class IntSize;
     49     class KURL;
     50     class ResourceError;
     51     class ResourceRequest;
     52     class ResourceResponse;
     53     struct CrossThreadResourceResponseData;
     54     struct CrossThreadResourceRequestData;
     55 
     56     template<typename T> struct CrossThreadCopierPassThrough {
     57         typedef T Type;
     58         static Type copy(const T& parameter)
     59         {
     60             return parameter;
     61         }
     62     };
     63 
     64     template<bool isConvertibleToInteger, bool isThreadSafeRefCounted, bool isGarbageCollected, typename T> struct CrossThreadCopierBase;
     65 
     66     // Integers get passed through without any changes.
     67     template<typename T> struct CrossThreadCopierBase<true, false, false, T> : public CrossThreadCopierPassThrough<T> {
     68     };
     69 
     70     // To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and
     71     // a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file.
     72     template<> struct CrossThreadCopierBase<false, false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> {
     73     };
     74 
     75     template<> struct CrossThreadCopierBase<false, false, false, IntSize> : public CrossThreadCopierPassThrough<IntSize> {
     76     };
     77 
     78     // Custom copy methods.
     79     template<typename T> struct CrossThreadCopierBase<false, true, false, T> {
     80         typedef typename WTF::RemoveTemplate<T, RefPtr>::Type TypeWithoutRefPtr;
     81         typedef typename WTF::RemoveTemplate<TypeWithoutRefPtr, PassRefPtr>::Type TypeWithoutPassRefPtr;
     82         typedef typename WTF::RemovePointer<TypeWithoutPassRefPtr>::Type RefCountedType;
     83 
     84         // Verify that only one of the above did a change.
     85         COMPILE_ASSERT((WTF::IsSameType<RefPtr<RefCountedType>, T>::value
     86                         || WTF::IsSameType<PassRefPtr<RefCountedType>, T>::value
     87                         || WTF::IsSameType<RefCountedType*, T>::value),
     88                        OnlyAllowOneTypeModification);
     89 
     90         typedef PassRefPtr<RefCountedType> Type;
     91         static Type copy(const T& refPtr)
     92         {
     93             return refPtr;
     94         }
     95     };
     96 
     97     template<typename T> struct CrossThreadCopierBase<false, false, false, PassOwnPtr<T> > {
     98         typedef PassOwnPtr<T> Type;
     99         static Type copy(Type ownPtr)
    100         {
    101             return ownPtr;
    102         }
    103     };
    104 
    105     template<typename T> struct CrossThreadCopierBase<false, false, false, WeakMember<T>*> {
    106         typedef WeakMember<T>* Type;
    107         static Type copy(Type ptr)
    108         {
    109             return ptr;
    110         }
    111     };
    112 
    113     template<> struct CrossThreadCopierBase<false, false, false, KURL> {
    114         typedef KURL Type;
    115         PLATFORM_EXPORT static Type copy(const KURL&);
    116     };
    117 
    118     template<> struct CrossThreadCopierBase<false, false, false, String> {
    119         typedef String Type;
    120         PLATFORM_EXPORT static Type copy(const String&);
    121     };
    122 
    123     template<> struct CrossThreadCopierBase<false, false, false, ResourceError> {
    124         typedef ResourceError Type;
    125         PLATFORM_EXPORT static Type copy(const ResourceError&);
    126     };
    127 
    128     template<> struct CrossThreadCopierBase<false, false, false, ResourceRequest> {
    129         typedef PassOwnPtr<CrossThreadResourceRequestData> Type;
    130         PLATFORM_EXPORT static Type copy(const ResourceRequest&);
    131     };
    132 
    133     template<> struct CrossThreadCopierBase<false, false, false, ResourceResponse> {
    134         typedef PassOwnPtr<CrossThreadResourceResponseData> Type;
    135         PLATFORM_EXPORT static Type copy(const ResourceResponse&);
    136     };
    137 
    138     template<typename T> struct CrossThreadCopierBase<false, false, true, T> {
    139         typedef typename WTF::RemovePointer<T>::Type TypeWithoutPointer;
    140         typedef RawPtr<TypeWithoutPointer> Type;
    141         static Type copy(const T& ptr)
    142         {
    143             return ptr;
    144         }
    145     };
    146 
    147     template<typename T> struct CrossThreadCopierBase<false, false, true, RawPtr<T> > {
    148         typedef RawPtr<T> Type;
    149         static Type copy(const Type& ptr)
    150         {
    151             return ptr;
    152         }
    153     };
    154 
    155     template<typename T> struct CrossThreadCopierBase<false, false, true, Member<T> > {
    156         typedef RawPtr<T> Type;
    157         static Type copy(const Member<T>& ptr)
    158         {
    159             return ptr;
    160         }
    161     };
    162 
    163     template<typename T> struct CrossThreadCopierBase<false, false, true, WeakMember<T> > {
    164         typedef RawPtr<T> Type;
    165         static Type copy(const WeakMember<T>& ptr)
    166         {
    167             return ptr;
    168         }
    169     };
    170 
    171     template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<WTF::IsConvertibleToInteger<T>::value,
    172         WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RefPtr>::Type, ThreadSafeRefCounted>::value
    173             || WTF::IsSubclassOfTemplate<typename WTF::RemovePointer<T>::Type, ThreadSafeRefCounted>::value
    174             || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, PassRefPtr>::Type, ThreadSafeRefCounted>::value,
    175         WTF::IsSubclassOfTemplate<typename WTF::RemovePointer<T>::Type, GarbageCollected>::value
    176             || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RawPtr>::Type, GarbageCollected>::value
    177             || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, Member>::Type, GarbageCollected>::value
    178             || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, WeakMember>::Type, GarbageCollected>::value,
    179         T> {
    180     };
    181 
    182     template<typename T> struct AllowCrossThreadAccessWrapper {
    183         STACK_ALLOCATED();
    184     public:
    185         explicit AllowCrossThreadAccessWrapper(T* value) : m_value(value) { }
    186         T* value() const { return m_value; }
    187     private:
    188         // This raw pointer is safe since AllowCrossThreadAccessWrapper is
    189         // always stack-allocated. Ideally this should be Member<T> if T is
    190         // garbage-collected and T* otherwise, but we don't want to introduce
    191         // another template magic just for distinguishing Member<T> from T*.
    192         // From the perspective of GC, T* always works correctly.
    193         GC_PLUGIN_IGNORE("")
    194         T* m_value;
    195     };
    196 
    197     template<typename T> struct CrossThreadCopierBase<false, false, false, AllowCrossThreadAccessWrapper<T> > {
    198         typedef T* Type;
    199         static Type copy(const AllowCrossThreadAccessWrapper<T>& wrapper) { return wrapper.value(); }
    200     };
    201 
    202     template<typename T> AllowCrossThreadAccessWrapper<T> AllowCrossThreadAccess(T* value)
    203     {
    204         return AllowCrossThreadAccessWrapper<T>(value);
    205     }
    206 
    207     // FIXME: Move to a different header file. AllowAccessLater is for cross-thread access
    208     // that is not cross-thread (tasks posted to a queue guaranteed to run on the same thread).
    209     template<typename T> struct AllowAccessLaterWrapper {
    210     public:
    211         explicit AllowAccessLaterWrapper(T* value) : m_value(value) { }
    212         T* value() const { return m_value; }
    213     private:
    214         T* m_value;
    215     };
    216 
    217     template<typename T> struct CrossThreadCopierBase<false, false, false, AllowAccessLaterWrapper<T> > {
    218         typedef T* Type;
    219         static Type copy(const AllowAccessLaterWrapper<T>& wrapper) { return wrapper.value(); }
    220     };
    221 
    222     template<typename T> AllowAccessLaterWrapper<T> AllowAccessLater(T* value)
    223     {
    224         return AllowAccessLaterWrapper<T>(value);
    225     }
    226 
    227 
    228 } // namespace blink
    229 
    230 #endif // CrossThreadCopier_h
    231