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