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/RefPtr.h"
     41 #include "wtf/ThreadSafeRefCounted.h"
     42 #include "wtf/TypeTraits.h"
     43 
     44 namespace WebCore {
     45 
     46     class IntRect;
     47     class IntSize;
     48     class KURL;
     49     class ResourceError;
     50     class ResourceRequest;
     51     class ResourceResponse;
     52     struct CrossThreadResourceResponseData;
     53     struct CrossThreadResourceRequestData;
     54     struct ThreadableLoaderOptions;
     55     struct ResourceLoaderOptions;
     56 
     57     template<typename T> struct CrossThreadCopierPassThrough {
     58         typedef T Type;
     59         static Type copy(const T& parameter)
     60         {
     61             return parameter;
     62         }
     63     };
     64 
     65     template<bool isConvertibleToInteger, bool isThreadSafeRefCounted, bool isGarbageCollected, typename T> struct CrossThreadCopierBase;
     66 
     67     // Integers get passed through without any changes.
     68     template<typename T> struct CrossThreadCopierBase<true, false, false, T> : public CrossThreadCopierPassThrough<T> {
     69     };
     70 
     71     // To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and
     72     // a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file.
     73     template<> struct CrossThreadCopierBase<false, false, false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> {
     74     };
     75 
     76     template<> struct CrossThreadCopierBase<false, false, false, ResourceLoaderOptions> : public CrossThreadCopierPassThrough<ResourceLoaderOptions> {
     77     };
     78 
     79     template<> struct CrossThreadCopierBase<false, false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> {
     80     };
     81 
     82     template<> struct CrossThreadCopierBase<false, false, false, IntSize> : public CrossThreadCopierPassThrough<IntSize> {
     83     };
     84 
     85     // Custom copy methods.
     86     template<typename T> struct CrossThreadCopierBase<false, true, false, T> {
     87         typedef typename WTF::RemoveTemplate<T, RefPtr>::Type TypeWithoutRefPtr;
     88         typedef typename WTF::RemoveTemplate<TypeWithoutRefPtr, PassRefPtr>::Type TypeWithoutPassRefPtr;
     89         typedef typename WTF::RemovePointer<TypeWithoutPassRefPtr>::Type RefCountedType;
     90 
     91         // Verify that only one of the above did a change.
     92         COMPILE_ASSERT((WTF::IsSameType<RefPtr<RefCountedType>, T>::value
     93                         || WTF::IsSameType<PassRefPtr<RefCountedType>, T>::value
     94                         || WTF::IsSameType<RefCountedType*, T>::value),
     95                        OnlyAllowOneTypeModification);
     96 
     97         typedef PassRefPtr<RefCountedType> Type;
     98         static Type copy(const T& refPtr)
     99         {
    100             return refPtr;
    101         }
    102     };
    103 
    104     template<typename T> struct CrossThreadCopierBase<false, false, false, PassOwnPtr<T> > {
    105         typedef PassOwnPtr<T> Type;
    106         static Type copy(Type ownPtr)
    107         {
    108             return ownPtr;
    109         }
    110     };
    111 
    112     template<> struct CrossThreadCopierBase<false, false, false, KURL> {
    113         typedef KURL Type;
    114         PLATFORM_EXPORT static Type copy(const KURL&);
    115     };
    116 
    117     template<> struct CrossThreadCopierBase<false, false, false, String> {
    118         typedef String Type;
    119         PLATFORM_EXPORT static Type copy(const String&);
    120     };
    121 
    122     template<> struct CrossThreadCopierBase<false, false, false, ResourceError> {
    123         typedef ResourceError Type;
    124         PLATFORM_EXPORT static Type copy(const ResourceError&);
    125     };
    126 
    127     template<> struct CrossThreadCopierBase<false, false, false, ResourceRequest> {
    128         typedef PassOwnPtr<CrossThreadResourceRequestData> Type;
    129         PLATFORM_EXPORT static Type copy(const ResourceRequest&);
    130     };
    131 
    132     template<> struct CrossThreadCopierBase<false, false, false, ResourceResponse> {
    133         typedef PassOwnPtr<CrossThreadResourceResponseData> Type;
    134         PLATFORM_EXPORT static Type copy(const ResourceResponse&);
    135     };
    136 
    137     template<typename T> struct CrossThreadCopierBase<false, false, true, T> {
    138         typedef typename WTF::RemovePointer<T>::Type TypeWithoutPointer;
    139         typedef PassRefPtrWillBeRawPtr<TypeWithoutPointer> Type;
    140         static Type copy(const T& ptr)
    141         {
    142             return ptr;
    143         }
    144     };
    145 
    146     template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<WTF::IsConvertibleToInteger<T>::value,
    147         WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RefPtr>::Type, ThreadSafeRefCounted>::value
    148             || WTF::IsSubclassOfTemplate<typename WTF::RemovePointer<T>::Type, ThreadSafeRefCounted>::value
    149             || WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, PassRefPtr>::Type, ThreadSafeRefCounted>::value,
    150         WTF::IsSubclassOfTemplate<typename WTF::RemovePointer<T>::Type, GarbageCollected>::value,
    151         T> {
    152     };
    153 
    154     template<typename T> struct AllowCrossThreadAccessWrapper {
    155     public:
    156         explicit AllowCrossThreadAccessWrapper(T* value) : m_value(value) { }
    157         T* value() const { return m_value; }
    158     private:
    159         T* m_value;
    160     };
    161 
    162     template<typename T> struct CrossThreadCopierBase<false, false, false, AllowCrossThreadAccessWrapper<T> > {
    163         typedef T* Type;
    164         static Type copy(const AllowCrossThreadAccessWrapper<T>& wrapper) { return wrapper.value(); }
    165     };
    166 
    167     template<typename T> AllowCrossThreadAccessWrapper<T> AllowCrossThreadAccess(T* value)
    168     {
    169         return AllowCrossThreadAccessWrapper<T>(value);
    170     }
    171 
    172     // FIXME: Move to a different header file. AllowAccessLater is for cross-thread access
    173     // that is not cross-thread (tasks posted to a queue guaranteed to run on the same thread).
    174     template<typename T> struct AllowAccessLaterWrapper {
    175     public:
    176         explicit AllowAccessLaterWrapper(T* value) : m_value(value) { }
    177         T* value() const { return m_value; }
    178     private:
    179         T* m_value;
    180     };
    181 
    182     template<typename T> struct CrossThreadCopierBase<false, false, false, AllowAccessLaterWrapper<T> > {
    183         typedef T* Type;
    184         static Type copy(const AllowAccessLaterWrapper<T>& wrapper) { return wrapper.value(); }
    185     };
    186 
    187     template<typename T> AllowAccessLaterWrapper<T> AllowAccessLater(T* value)
    188     {
    189         return AllowAccessLaterWrapper<T>(value);
    190     }
    191 
    192 
    193 } // namespace WebCore
    194 
    195 #endif // CrossThreadCopier_h
    196