Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 namespace blink { | 46 namespace blink { |
| 47 | 47 |
| 48 // By default, the destruction of a WebPrivatePtr<> must happen on the same | 48 // By default, the destruction of a WebPrivatePtr<> must happen on the same |
| 49 // thread that created it, but can optionally be allowed to happen on | 49 // thread that created it, but can optionally be allowed to happen on |
| 50 // another thread. | 50 // another thread. |
| 51 enum WebPrivatePtrDestruction { | 51 enum WebPrivatePtrDestruction { |
| 52 WebPrivatePtrDestructionSameThread, | 52 WebPrivatePtrDestructionSameThread, |
| 53 WebPrivatePtrDestructionCrossThread, | 53 WebPrivatePtrDestructionCrossThread, |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 // The WebPrivatePtr<> holds by default a strong reference to its Blink object, | |
| 57 // but Blink GC managed objects also support keeping a weak reference by | |
| 58 // way of WebPrivatePtr<>. | |
| 59 enum class WebPrivatePtrStrength { | |
| 60 Normal, | |
| 61 Weak, | |
| 62 }; | |
| 63 | |
| 56 #if INSIDE_BLINK | 64 #if INSIDE_BLINK |
| 57 enum LifetimeManagementType { | 65 enum LifetimeManagementType { |
| 58 RefCountedLifetime, | 66 RefCountedLifetime, |
| 59 GarbageCollectedLifetime, | 67 GarbageCollectedLifetime, |
| 60 RefCountedGarbageCollectedLifetime | 68 RefCountedGarbageCollectedLifetime |
| 61 }; | 69 }; |
| 62 | 70 |
| 63 template<typename T> | 71 template<typename T> |
| 64 class LifetimeOf { | 72 class LifetimeOf { |
| 65 static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, GarbageC ollected>::value || IsGarbageCollectedMixin<T>::value; | 73 static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, GarbageC ollected>::value || IsGarbageCollectedMixin<T>::value; |
| 66 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T , RefCountedGarbageCollected>::value; | 74 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T , RefCountedGarbageCollected>::value; |
| 67 public: | 75 public: |
| 68 static const LifetimeManagementType value = | 76 static const LifetimeManagementType value = |
| 69 !isGarbageCollected ? RefCountedLifetime : | 77 !isGarbageCollected ? RefCountedLifetime : |
| 70 isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : Garb ageCollectedLifetime; | 78 isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : Garb ageCollectedLifetime; |
| 71 }; | 79 }; |
| 72 | 80 |
| 73 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, LifetimeMa nagementType lifetime> | 81 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, WebPrivate PtrStrength strongOrWeak, LifetimeManagementType lifetime> |
| 74 class PtrStorageImpl; | 82 class PtrStorageImpl; |
| 75 | 83 |
| 76 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 84 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, WebPrivate PtrStrength strongOrWeak> |
| 77 class PtrStorageImpl<T, crossThreadDestruction, RefCountedLifetime> { | 85 class PtrStorageImpl<T, crossThreadDestruction, strongOrWeak, RefCountedLifetime > { |
| 78 public: | 86 public: |
| 79 typedef PassRefPtr<T> BlinkPtrType; | 87 typedef PassRefPtr<T> BlinkPtrType; |
| 80 | 88 |
| 81 void assign(const BlinkPtrType& val) | 89 void assign(const BlinkPtrType& val) |
| 82 { | 90 { |
| 83 static_assert(crossThreadDestruction == WebPrivatePtrDestructionSameThre ad || WTF::IsSubclassOfTemplate<T, WTF::ThreadSafeRefCounted>::value, "Cross thr ead destructible class must derive from ThreadSafeRefCounted<>"); | 91 static_assert(crossThreadDestruction == WebPrivatePtrDestructionSameThre ad || WTF::IsSubclassOfTemplate<T, WTF::ThreadSafeRefCounted>::value, "Cross thr ead destructible class must derive from ThreadSafeRefCounted<>"); |
| 92 static_assert(strongOrWeak == WebPrivatePtrStrength::Normal, "Ref-counte d classes do not support weak WebPrivatePtr<> references"); | |
| 84 release(); | 93 release(); |
| 85 m_ptr = val.leakRef(); | 94 m_ptr = val.leakRef(); |
| 86 } | 95 } |
| 87 | 96 |
| 88 void assign(const PtrStorageImpl& other) | 97 void assign(const PtrStorageImpl& other) |
| 89 { | 98 { |
| 90 release(); | 99 release(); |
| 91 T* val = other.get(); | 100 T* val = other.get(); |
| 92 WTF::refIfNotNull(val); | 101 WTF::refIfNotNull(val); |
| 93 m_ptr = val; | 102 m_ptr = val; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 105 void release() | 114 void release() |
| 106 { | 115 { |
| 107 WTF::derefIfNotNull(m_ptr); | 116 WTF::derefIfNotNull(m_ptr); |
| 108 m_ptr = 0; | 117 m_ptr = 0; |
| 109 } | 118 } |
| 110 | 119 |
| 111 private: | 120 private: |
| 112 T* m_ptr; | 121 T* m_ptr; |
| 113 }; | 122 }; |
| 114 | 123 |
| 115 template <typename T, WebPrivatePtrDestruction> | 124 template <typename T, WebPrivatePtrDestruction, WebPrivatePtrStrength> |
| 116 struct WebPrivatePtrPersistentStorageType { | 125 struct WebPrivatePtrPersistentStorageType { |
| 117 public: | 126 public: |
| 118 using Type = Persistent<T>; | 127 using Type = Persistent<T>; |
| 119 }; | 128 }; |
| 120 | 129 |
| 121 template <typename T> | 130 template <typename T> |
| 122 struct WebPrivatePtrPersistentStorageType<T, WebPrivatePtrDestructionCrossThread > { | 131 struct WebPrivatePtrPersistentStorageType<T, WebPrivatePtrDestructionSameThread, WebPrivatePtrStrength::Weak> { |
| 132 public: | |
| 133 using Type = WeakPersistent<T>; | |
| 134 }; | |
| 135 | |
| 136 template <typename T> | |
| 137 struct WebPrivatePtrPersistentStorageType<T, WebPrivatePtrDestructionCrossThread , WebPrivatePtrStrength::Normal> { | |
| 123 public: | 138 public: |
| 124 using Type = CrossThreadPersistent<T>; | 139 using Type = CrossThreadPersistent<T>; |
| 125 }; | 140 }; |
| 126 | 141 |
| 127 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 142 template <typename T> |
| 128 class PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> { | 143 struct WebPrivatePtrPersistentStorageType<T, WebPrivatePtrDestructionCrossThread , WebPrivatePtrStrength::Weak> { |
| 144 public: | |
| 145 using Type = CrossThreadWeakPersistent<T>; | |
| 146 }; | |
| 147 | |
| 148 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, WebPrivate PtrStrength strongOrWeak> | |
| 149 class PtrStorageImpl<T, crossThreadDestruction, strongOrWeak, GarbageCollect edLifetime> { | |
|
hiroshige
2016/01/27 03:55:01
nit: no indent needed here.
sof
2016/01/29 09:12:23
oops, thanks for catching that.
| |
| 129 public: | 150 public: |
| 130 void assign(const RawPtr<T>& val) | 151 void assign(const RawPtr<T>& val) |
| 131 { | 152 { |
| 132 if (!val) { | 153 if (!val) { |
| 133 release(); | 154 release(); |
| 134 return; | 155 return; |
| 135 } | 156 } |
| 136 | 157 |
| 137 if (!m_handle) | 158 if (!m_handle) |
| 138 m_handle = new (typename WebPrivatePtrPersistentStorageType<T, cross ThreadDestruction>::Type)(); | 159 m_handle = new (typename WebPrivatePtrPersistentStorageType<T, cross ThreadDestruction, strongOrWeak>::Type)(); |
| 139 | 160 |
| 140 (*m_handle) = val; | 161 (*m_handle) = val; |
| 141 } | 162 } |
| 142 | 163 |
| 143 void assign(T* ptr) { assign(RawPtr<T>(ptr)); } | 164 void assign(T* ptr) { assign(RawPtr<T>(ptr)); } |
| 144 template<typename U> void assign(const RawPtr<U>& val) { assign(RawPtr<T>(va l)); } | 165 template<typename U> void assign(const RawPtr<U>& val) { assign(RawPtr<T>(va l)); } |
| 145 | 166 |
| 146 void assign(const PtrStorageImpl& other) { assign(other.get()); } | 167 void assign(const PtrStorageImpl& other) { assign(other.get()); } |
| 147 | 168 |
| 148 void moveFrom(PtrStorageImpl& other) | 169 void moveFrom(PtrStorageImpl& other) |
| 149 { | 170 { |
| 150 release(); | 171 release(); |
| 151 m_handle = other.m_handle; | 172 m_handle = other.m_handle; |
| 152 other.m_handle = 0; | 173 other.m_handle = 0; |
| 153 } | 174 } |
| 154 | 175 |
| 155 T* get() const { return m_handle ? m_handle->get() : 0; } | 176 T* get() const { return m_handle ? m_handle->get() : 0; } |
| 156 | 177 |
| 157 void release() | 178 void release() |
| 158 { | 179 { |
| 159 delete m_handle; | 180 delete m_handle; |
| 160 m_handle = 0; | 181 m_handle = 0; |
| 161 } | 182 } |
| 162 | 183 |
| 163 private: | 184 private: |
| 164 typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction>::Type * m_handle; | 185 typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction, stron gOrWeak>::Type* m_handle; |
| 165 }; | 186 }; |
| 166 | 187 |
| 167 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 188 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, WebPrivate PtrStrength strongOrWeak> |
| 168 class PtrStorageImpl<T, crossThreadDestruction, RefCountedGarbageCollectedLifeti me> : public PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> { | 189 class PtrStorageImpl<T, crossThreadDestruction, strongOrWeak, RefCountedGarbageC ollectedLifetime> : public PtrStorageImpl<T, crossThreadDestruction, strongOrWea k, GarbageCollectedLifetime> { |
| 169 public: | 190 public: |
| 170 void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, crossT hreadDestruction, GarbageCollectedLifetime>::assign(val.get()); } | 191 void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, crossT hreadDestruction, strongOrWeak, GarbageCollectedLifetime>::assign(val.get()); } |
| 171 | 192 |
| 172 void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, crossThreadDest ruction, GarbageCollectedLifetime>::assign(other.get()); } | 193 void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, crossThreadDest ruction, strongOrWeak, GarbageCollectedLifetime>::assign(other.get()); } |
| 173 }; | 194 }; |
| 174 | 195 |
| 175 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 196 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, WebPrivate PtrStrength strongOrWeak> |
| 176 class PtrStorage : public PtrStorageImpl<T, crossThreadDestruction, LifetimeOf<T >::value> { | 197 class PtrStorage : public PtrStorageImpl<T, crossThreadDestruction, strongOrWeak , LifetimeOf<T>::value> { |
| 177 public: | 198 public: |
| 178 static PtrStorage& fromSlot(void** slot) | 199 static PtrStorage& fromSlot(void** slot) |
| 179 { | 200 { |
| 180 static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t he size of a pointer"); | 201 static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t he size of a pointer"); |
| 181 return *reinterpret_cast<PtrStorage*>(slot); | 202 return *reinterpret_cast<PtrStorage*>(slot); |
| 182 } | 203 } |
| 183 | 204 |
| 184 static const PtrStorage& fromSlot(void* const* slot) | 205 static const PtrStorage& fromSlot(void* const* slot) |
| 185 { | 206 { |
| 186 static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t he size of a pointer"); | 207 static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t he size of a pointer"); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 // #endif | 244 // #endif |
| 224 // | 245 // |
| 225 // private: | 246 // private: |
| 226 // WebPrivatePtr<Foo> m_private; | 247 // WebPrivatePtr<Foo> m_private; |
| 227 // }; | 248 // }; |
| 228 // | 249 // |
| 229 // // WebFoo.cpp | 250 // // WebFoo.cpp |
| 230 // WebFoo::~WebFoo() { m_private.reset(); } | 251 // WebFoo::~WebFoo() { m_private.reset(); } |
| 231 // void WebFoo::assign(const WebFoo& other) { ... } | 252 // void WebFoo::assign(const WebFoo& other) { ... } |
| 232 // | 253 // |
| 233 template <typename T, WebPrivatePtrDestruction crossThreadDestruction = WebPriva tePtrDestructionSameThread> | 254 template <typename T, WebPrivatePtrDestruction crossThreadDestruction = WebPriva tePtrDestructionSameThread, WebPrivatePtrStrength strongOrWeak = WebPrivatePtrSt rength::Normal> |
| 234 class WebPrivatePtr { | 255 class WebPrivatePtr { |
| 235 public: | 256 public: |
| 236 WebPrivatePtr() : m_storage(0) { } | 257 WebPrivatePtr() : m_storage(0) { } |
| 237 ~WebPrivatePtr() | 258 ~WebPrivatePtr() |
| 238 { | 259 { |
| 239 // We don't destruct the object pointed by m_ptr here because we don't | 260 // We don't destruct the object pointed by m_ptr here because we don't |
| 240 // want to expose destructors of core classes to embedders. We should | 261 // want to expose destructors of core classes to embedders. We should |
| 241 // call reset() manually in destructors of classes with WebPrivatePtr | 262 // call reset() manually in destructors of classes with WebPrivatePtr |
| 242 // members. | 263 // members. |
| 243 BLINK_ASSERT(!m_storage); | 264 BLINK_ASSERT(!m_storage); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 | 305 |
| 285 T* operator->() const | 306 T* operator->() const |
| 286 { | 307 { |
| 287 ASSERT(m_storage); | 308 ASSERT(m_storage); |
| 288 return get(); | 309 return get(); |
| 289 } | 310 } |
| 290 #endif | 311 #endif |
| 291 | 312 |
| 292 private: | 313 private: |
| 293 #if INSIDE_BLINK | 314 #if INSIDE_BLINK |
| 294 PtrStorage<T, crossThreadDestruction>& storage() { return PtrStorage<T, cros sThreadDestruction>::fromSlot(&m_storage); } | 315 PtrStorage<T, crossThreadDestruction, strongOrWeak>& storage() { return PtrS torage<T, crossThreadDestruction, strongOrWeak>::fromSlot(&m_storage); } |
| 295 const PtrStorage<T, crossThreadDestruction>& storage() const { return PtrSto rage<T, crossThreadDestruction>::fromSlot(&m_storage); } | 316 const PtrStorage<T, crossThreadDestruction, strongOrWeak>& storage() const { return PtrStorage<T, crossThreadDestruction, strongOrWeak>::fromSlot(&m_storage ); } |
| 296 #endif | 317 #endif |
| 297 | 318 |
| 298 #if !INSIDE_BLINK | 319 #if !INSIDE_BLINK |
| 299 // Disable the assignment operator; we define it above for when | 320 // Disable the assignment operator; we define it above for when |
| 300 // INSIDE_BLINK is set, but we need to make sure that it is not | 321 // INSIDE_BLINK is set, but we need to make sure that it is not |
| 301 // used outside there; the compiler-provided version won't handle reference | 322 // used outside there; the compiler-provided version won't handle reference |
| 302 // counting properly. | 323 // counting properly. |
| 303 WebPrivatePtr& operator=(const WebPrivatePtr& other); | 324 WebPrivatePtr& operator=(const WebPrivatePtr& other); |
| 304 #endif | 325 #endif |
| 305 // Disable the copy constructor; classes that contain a WebPrivatePtr | 326 // Disable the copy constructor; classes that contain a WebPrivatePtr |
| 306 // should implement their copy constructor using assign(). | 327 // should implement their copy constructor using assign(). |
| 307 WebPrivatePtr(const WebPrivatePtr&); | 328 WebPrivatePtr(const WebPrivatePtr&); |
| 308 | 329 |
| 309 void* m_storage; | 330 void* m_storage; |
| 310 }; | 331 }; |
| 311 | 332 |
| 312 } // namespace blink | 333 } // namespace blink |
| 313 | 334 |
| 314 #endif | 335 #endif // WebPrivatePtr_h |
| OLD | NEW |