2 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
31 #ifndef CrossThreadCopier_h
32 #define CrossThreadCopier_h
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>
47 class ResourceRequest;
48 class ResourceResponse;
49 struct CrossThreadResourceResponseData;
50 struct CrossThreadResourceRequestData;
51 struct ThreadableLoaderOptions;
53 struct CrossThreadCopierBaseHelper {
54 template<typename T> struct RemovePointer {
57 template<typename T> struct RemovePointer<T*> {
61 template<typename T> struct RemovePointer<RefPtr<T>> {
65 template<typename T> struct RemovePointer<PassRefPtr<T>> {
69 template<typename T> struct IsConvertibleToInteger {
70 static const bool value = std::is_integral<T>::value || std::is_convertible<T, long double>::value;
73 template<typename T> struct IsThreadSafeRefCountedPointer {
74 static const bool value = std::is_convertible<typename RemovePointer<T>::Type*, ThreadSafeRefCounted<typename RemovePointer<T>::Type>*>::value;
78 template<typename T> struct CrossThreadCopierPassThrough {
80 static Type copy(const T& parameter)
86 template<bool isConvertibleToInteger, bool isThreadSafeRefCounted, typename T> struct CrossThreadCopierBase;
88 // Integers get passed through without any changes.
89 template<typename T> struct CrossThreadCopierBase<true, false, T> : public CrossThreadCopierPassThrough<T> {
92 // To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and
93 // a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file.
94 template<> struct CrossThreadCopierBase<false, false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> {
97 template<> struct CrossThreadCopierBase<false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> {
100 template<> struct CrossThreadCopierBase<false, false, IntSize> : public CrossThreadCopierPassThrough<IntSize> {
103 // Custom copy methods.
104 template<typename T> struct CrossThreadCopierBase<false, true, T> {
105 typedef typename CrossThreadCopierBaseHelper::RemovePointer<T>::Type RefCountedType;
106 static_assert(std::is_convertible<RefCountedType*, ThreadSafeRefCounted<RefCountedType>*>::value, "T is not convertible to ThreadSafeRefCounted!");
108 typedef PassRefPtr<RefCountedType> Type;
109 static Type copy(const T& refPtr)
115 template<typename T> struct CrossThreadCopierBase<false, false, PassOwnPtr<T>> {
116 typedef PassOwnPtr<T> Type;
117 static Type copy(Type ownPtr)
123 template<> struct CrossThreadCopierBase<false, false, URL> {
125 static Type copy(const URL&);
128 template<> struct CrossThreadCopierBase<false, false, String> {
130 static Type copy(const String&);
133 template<> struct CrossThreadCopierBase<false, false, ResourceError> {
134 typedef ResourceError Type;
135 static Type copy(const ResourceError&);
138 template<> struct CrossThreadCopierBase<false, false, ResourceRequest> {
139 typedef PassOwnPtr<CrossThreadResourceRequestData> Type;
140 static Type copy(const ResourceRequest&);
143 template<> struct CrossThreadCopierBase<false, false, ResourceResponse> {
144 typedef PassOwnPtr<CrossThreadResourceResponseData> Type;
145 static Type copy(const ResourceResponse&);
148 #if ENABLE(INDEXED_DATABASE)
149 namespace IndexedDB {
150 enum class TransactionMode;
151 enum class CursorDirection;
152 enum class CursorType;
154 template<> struct CrossThreadCopierBase<false, false, IndexedDB::TransactionMode> {
155 static IndexedDB::TransactionMode copy(const IndexedDB::TransactionMode&);
157 template<> struct CrossThreadCopierBase<false, false, IndexedDB::CursorDirection> {
158 static IndexedDB::CursorDirection copy(const IndexedDB::CursorDirection&);
160 template<> struct CrossThreadCopierBase<false, false, IndexedDB::CursorType> {
161 static IndexedDB::CursorType copy(const IndexedDB::CursorType&);
164 struct IDBDatabaseMetadata;
165 template<> struct CrossThreadCopierBase<false, false, IDBDatabaseMetadata> {
166 typedef IDBDatabaseMetadata Type;
167 static Type copy(const IDBDatabaseMetadata&);
170 struct IDBIndexMetadata;
171 template<> struct CrossThreadCopierBase<false, false, IDBIndexMetadata> {
172 typedef IDBIndexMetadata Type;
173 static Type copy(const IDBIndexMetadata&);
177 template<> struct CrossThreadCopierBase<false, false, IDBKeyData> {
178 typedef IDBKeyData Type;
179 static Type copy(const IDBKeyData&);
182 struct IDBObjectStoreMetadata;
183 template<> struct CrossThreadCopierBase<false, false, IDBObjectStoreMetadata> {
184 typedef IDBObjectStoreMetadata Type;
185 static Type copy(const IDBObjectStoreMetadata&);
190 struct CrossThreadCopier : public CrossThreadCopierBase<CrossThreadCopierBaseHelper::IsConvertibleToInteger<T>::value, CrossThreadCopierBaseHelper::IsThreadSafeRefCountedPointer<T>::value, T> {
193 template<typename T> struct AllowCrossThreadAccessWrapper {
195 explicit AllowCrossThreadAccessWrapper(T* value) : m_value(value) { }
196 T* value() const { return m_value; }
201 template<typename T> struct CrossThreadCopierBase<false, false, AllowCrossThreadAccessWrapper<T>> {
203 static Type copy(const AllowCrossThreadAccessWrapper<T>& wrapper) { return wrapper.value(); }
206 template<typename T> AllowCrossThreadAccessWrapper<T> AllowCrossThreadAccess(T* value)
208 return AllowCrossThreadAccessWrapper<T>(value);
211 // FIXME: Move to a different header file. AllowAccessLater is for cross-thread access
212 // that is not cross-thread (tasks posted to a queue guaranteed to run on the same thread).
213 template<typename T> struct AllowAccessLaterWrapper {
215 explicit AllowAccessLaterWrapper(T* value) : m_value(value) { }
216 T* value() const { return m_value; }
221 template<typename T> struct CrossThreadCopierBase<false, false, AllowAccessLaterWrapper<T>> {
223 static Type copy(const AllowAccessLaterWrapper<T>& wrapper) { return wrapper.value(); }
226 template<typename T> AllowAccessLaterWrapper<T> AllowAccessLater(T* value)
228 return AllowAccessLaterWrapper<T>(value);
232 } // namespace WebCore
234 #endif // CrossThreadCopier_h