Chromium Code Reviews| Index: public/platform/WebPrivatePtr.h |
| diff --git a/public/platform/WebPrivatePtr.h b/public/platform/WebPrivatePtr.h |
| index f62961f062b7e81375a0ff153d9aa1659edc8968..f4e6bf4e97693ed2eeeb4b1a3b3c58a995d28a4f 100644 |
| --- a/public/platform/WebPrivatePtr.h |
| +++ b/public/platform/WebPrivatePtr.h |
| @@ -39,8 +39,19 @@ |
| #include "wtf/TypeTraits.h" |
| #endif |
| +namespace WTF { |
| +template<class T> class ThreadSafeRefCounted; |
| +} |
| + |
| namespace blink { |
| +// By default, the destruction of a WebPrivatePtr<> must happen on the same |
| +// thread, but can be allowed to happen on another thread. |
| +enum WebPrivatePtrDestruction { |
| + SameThreadDestruction, |
|
tkent
2015/07/23 23:28:09
The enum items should be WebPrivatePtrDestruction
sof
2015/07/24 05:25:21
Thanks, aligned. And preferable to export & use th
|
| + AllowCrossThreadDestruction, |
| +}; |
| + |
| #if INSIDE_BLINK |
| enum LifetimeManagementType { |
| RefCountedLifetime, |
| @@ -58,16 +69,17 @@ public: |
| isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : GarbageCollectedLifetime; |
| }; |
| -template<typename T, LifetimeManagementType lifetime> |
| +template<typename T, WebPrivatePtrDestruction crossThreadDestruction, LifetimeManagementType lifetime> |
| class PtrStorageImpl; |
| -template<typename T> |
| -class PtrStorageImpl<T, RefCountedLifetime> { |
| +template<typename T, WebPrivatePtrDestruction crossThreadDestruction> |
| +class PtrStorageImpl<T, crossThreadDestruction, RefCountedLifetime> { |
| public: |
| typedef PassRefPtr<T> BlinkPtrType; |
| void assign(const BlinkPtrType& val) |
| { |
| + static_assert(crossThreadDestruction == SameThreadDestruction || WTF::IsSubclassOfTemplate<T, WTF::ThreadSafeRefCounted>::value, "Cross thread destructible class must derive from ThreadSafeRefCounted<>"); |
| release(); |
| m_ptr = val.leakRef(); |
| } |
| @@ -99,8 +111,20 @@ private: |
| T* m_ptr; |
| }; |
| -template<typename T> |
| -class PtrStorageImpl<T, GarbageCollectedLifetime> { |
| +template <typename T, WebPrivatePtrDestruction> |
| +struct WebPrivatePtrPersistentStorageType { |
| +public: |
| + using Type = Persistent<T>; |
| +}; |
| + |
| +template <typename T> |
| +struct WebPrivatePtrPersistentStorageType<T, AllowCrossThreadDestruction> { |
| +public: |
| + using Type = CrossThreadPersistent<T>; |
| +}; |
| + |
| +template<typename T, WebPrivatePtrDestruction crossThreadDestruction> |
| +class PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> { |
| public: |
| void assign(const RawPtr<T>& val) |
| { |
| @@ -110,7 +134,7 @@ public: |
| } |
| if (!m_handle) |
| - m_handle = new Persistent<T>(); |
| + m_handle = new (typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction>::Type)(); |
| (*m_handle) = val; |
| } |
| @@ -136,19 +160,19 @@ public: |
| } |
| private: |
| - Persistent<T>* m_handle; |
| + typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction>::Type* m_handle; |
| }; |
| -template<typename T> |
| -class PtrStorageImpl<T, RefCountedGarbageCollectedLifetime> : public PtrStorageImpl<T, GarbageCollectedLifetime> { |
| +template<typename T, WebPrivatePtrDestruction crossThreadDestruction> |
| +class PtrStorageImpl<T, crossThreadDestruction, RefCountedGarbageCollectedLifetime> : public PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> { |
| public: |
| - void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, GarbageCollectedLifetime>::assign(val.get()); } |
| + void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime>::assign(val.get()); } |
| - void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, GarbageCollectedLifetime>::assign(other.get()); } |
| + void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime>::assign(other.get()); } |
| }; |
| -template<typename T> |
| -class PtrStorage : public PtrStorageImpl<T, LifetimeOf<T>::value> { |
| +template<typename T, WebPrivatePtrDestruction crossThreadDestruction> |
| +class PtrStorage : public PtrStorageImpl<T, crossThreadDestruction, LifetimeOf<T>::value> { |
| public: |
| static PtrStorage& fromSlot(void** slot) |
| { |
| @@ -169,7 +193,6 @@ private: |
| }; |
| #endif |
| - |
| // This class is an implementation detail of the Blink API. It exists to help |
| // simplify the implementation of Blink interfaces that merely wrap a reference |
| // counted WebCore class. |
| @@ -206,7 +229,7 @@ private: |
| // WebFoo::~WebFoo() { m_private.reset(); } |
| // void WebFoo::assign(const WebFoo& other) { ... } |
| // |
| -template <typename T> |
| +template <typename T, WebPrivatePtrDestruction crossThreadDestruction = SameThreadDestruction> |
| class WebPrivatePtr { |
| public: |
| WebPrivatePtr() : m_storage(0) { } |
| @@ -231,20 +254,20 @@ public: |
| void reset() { storage().release(); } |
| - WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other) |
| + WebPrivatePtr& operator=(const WebPrivatePtr& other) |
| { |
| storage().assign(other.storage()); |
| return *this; |
| } |
| - void moveFrom(WebPrivatePtr<T>& other) |
| + void moveFrom(WebPrivatePtr& other) |
| { |
| storage().moveFrom(other.storage()); |
| return; |
| } |
| template<typename U> |
| - WebPrivatePtr<T>& operator=(const U& ptr) |
| + WebPrivatePtr& operator=(const U& ptr) |
| { |
| storage().assign(ptr); |
| return *this; |
| @@ -267,8 +290,8 @@ public: |
| private: |
| #if INSIDE_BLINK |
| - PtrStorage<T>& storage() { return PtrStorage<T>::fromSlot(&m_storage); } |
| - const PtrStorage<T>& storage() const { return PtrStorage<T>::fromSlot(&m_storage); } |
| + PtrStorage<T, crossThreadDestruction>& storage() { return PtrStorage<T, crossThreadDestruction>::fromSlot(&m_storage); } |
| + const PtrStorage<T, crossThreadDestruction>& storage() const { return PtrStorage<T, crossThreadDestruction>::fromSlot(&m_storage); } |
| #endif |
| #if !INSIDE_BLINK |
| @@ -276,11 +299,11 @@ private: |
| // INSIDE_BLINK is set, but we need to make sure that it is not |
| // used outside there; the compiler-provided version won't handle reference |
| // counting properly. |
| - WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other); |
| + WebPrivatePtr& operator=(const WebPrivatePtr& other); |
| #endif |
| // Disable the copy constructor; classes that contain a WebPrivatePtr |
| // should implement their copy constructor using assign(). |
| - WebPrivatePtr(const WebPrivatePtr<T>&); |
| + WebPrivatePtr(const WebPrivatePtr&); |
| void* m_storage; |
| }; |