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 16 matching lines...) Expand all Loading... | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #ifndef WebPrivatePtr_h | 31 #ifndef WebPrivatePtr_h |
32 #define WebPrivatePtr_h | 32 #define WebPrivatePtr_h |
33 | 33 |
34 #include "WebCommon.h" | 34 #include "WebCommon.h" |
35 | 35 |
36 #if INSIDE_BLINK | 36 #if INSIDE_BLINK |
37 #include "heap/Handle.h" | |
37 #include "wtf/PassRefPtr.h" | 38 #include "wtf/PassRefPtr.h" |
39 #include "wtf/TypeTraits.h" | |
38 #endif | 40 #endif |
39 | 41 |
40 namespace blink { | 42 namespace blink { |
41 | 43 |
44 #if INSIDE_BLINK | |
45 enum LifetimeManagementType { | |
46 RefCountedLifetime, | |
47 GarbageCollectedLifetime, | |
48 RefCountedGarbageCollectedLifetime | |
49 }; | |
50 | |
51 template<typename T> | |
52 class LifetimeOf { | |
53 static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, WebCore: :GarbageCollected>::value; | |
54 static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T , WebCore::RefCountedGarbageCollected>::value; | |
55 public: | |
56 static const LifetimeManagementType value = | |
57 !isGarbageCollected ? RefCountedLifetime : | |
58 isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : Garb ageCollectedLifetime; | |
59 }; | |
60 | |
61 template<typename T, LifetimeManagementType lifetime> | |
62 class PtrStorageImpl; | |
63 | |
64 template<typename T> | |
65 class PtrStorageImpl<T, RefCountedLifetime> { | |
66 public: | |
67 typedef PassRefPtr<T> BlinkPtrType; | |
68 | |
69 void assign(const BlinkPtrType& val) | |
70 { | |
71 release(); | |
72 m_ptr = val.leakRef(); | |
73 } | |
74 | |
75 void assign(const PtrStorageImpl& other) | |
76 { | |
77 release(); | |
78 T* val = other.get(); | |
79 if (val) | |
80 val->ref(); | |
81 m_ptr = val; | |
82 } | |
83 | |
84 T* get() const { return m_ptr; } | |
85 | |
86 void release() | |
87 { | |
88 if (m_ptr) | |
89 m_ptr->deref(); | |
90 m_ptr = 0; | |
91 } | |
92 | |
93 private: | |
94 T* m_ptr; | |
95 }; | |
96 | |
97 template<typename T> | |
98 class PtrStorageImpl<T, GarbageCollectedLifetime> { | |
99 public: | |
100 void assign(const RawPtr<T>& val) | |
101 { | |
102 if (!val) { | |
103 release(); | |
104 return; | |
105 } | |
106 | |
107 if (!m_handle) | |
108 m_handle = new WebCore::Persistent<T>(); | |
109 | |
110 (*m_handle) = val; | |
111 } | |
112 | |
113 void assign(T* ptr) { assign(RawPtr<T>(ptr)); } | |
114 | |
115 void assign(const PtrStorageImpl& other) { assign(other.get()); } | |
116 | |
117 T* get() const { return m_handle ? m_handle->get() : 0; } | |
118 | |
119 void release() | |
120 { | |
121 delete m_handle; | |
122 m_handle = 0; | |
123 } | |
124 | |
125 private: | |
126 WebCore::Persistent<T>* m_handle; | |
127 }; | |
128 | |
129 template<typename T> | |
130 class PtrStorageImpl<T, RefCountedGarbageCollectedLifetime> : public PtrStorageI mpl<T, GarbageCollectedLifetime> { | |
131 public: | |
132 void assign(const PassRefPtr<T>& val) { PtrStorageImpl<T, GarbageCollectedLi fetime>::assign(val.get()); } | |
133 | |
134 void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, GarbageCollecte dLifetime>::assign(other.get()); } | |
135 }; | |
136 | |
137 template<typename T> | |
138 class PtrStorage : public PtrStorageImpl<T, LifetimeOf<T>::value> { | |
139 public: | |
140 static PtrStorage& fromSlot(void** slot) | |
141 { | |
142 COMPILE_ASSERT(sizeof(PtrStorage) == sizeof(void*), PtrStorage_must_be_p ointer_size); | |
143 return *reinterpret_cast<PtrStorage*>(slot); | |
144 } | |
145 | |
146 static const PtrStorage& fromSlot(void* const* slot) | |
147 { | |
148 COMPILE_ASSERT(sizeof(PtrStorage) == sizeof(void*), PtrStorage_must_be_p ointer_size); | |
149 return *reinterpret_cast<const PtrStorage*>(slot); | |
150 } | |
151 | |
152 private: | |
153 // Prevent construction via normal means. | |
154 PtrStorage(); | |
155 PtrStorage(const PtrStorage&); | |
156 }; | |
157 #endif | |
158 | |
159 | |
42 // This class is an implementation detail of the Blink API. It exists to help | 160 // This class is an implementation detail of the Blink API. It exists to help |
43 // simplify the implementation of Blink interfaces that merely wrap a reference | 161 // simplify the implementation of Blink interfaces that merely wrap a reference |
44 // counted WebCore class. | 162 // counted WebCore class. |
45 // | 163 // |
46 // A typical implementation of a class which uses WebPrivatePtr might look like | 164 // A typical implementation of a class which uses WebPrivatePtr might look like |
47 // this: | 165 // this: |
48 // class WebFoo { | 166 // class WebFoo { |
49 // public: | 167 // public: |
50 // BLINK_EXPORT ~WebFoo(); | 168 // BLINK_EXPORT ~WebFoo(); |
51 // WebFoo() { } | 169 // WebFoo() { } |
(...skipping 19 matching lines...) Expand all Loading... | |
71 // WebPrivatePtr<WebCore::Foo> m_private; | 189 // WebPrivatePtr<WebCore::Foo> m_private; |
72 // }; | 190 // }; |
73 // | 191 // |
74 // // WebFoo.cpp | 192 // // WebFoo.cpp |
75 // WebFoo::~WebFoo() { m_private.reset(); } | 193 // WebFoo::~WebFoo() { m_private.reset(); } |
76 // void WebFoo::assign(const WebFoo& other) { ... } | 194 // void WebFoo::assign(const WebFoo& other) { ... } |
77 // | 195 // |
78 template <typename T> | 196 template <typename T> |
79 class WebPrivatePtr { | 197 class WebPrivatePtr { |
80 public: | 198 public: |
81 WebPrivatePtr() : m_ptr(0) { } | 199 WebPrivatePtr() : m_storage(0) { } |
82 ~WebPrivatePtr() | 200 ~WebPrivatePtr() |
83 { | 201 { |
84 // We don't destruct the object pointed by m_ptr here because we don't | 202 // We don't destruct the object pointed by m_ptr here because we don't |
85 // want to expose destructors of core classes to embedders. We should | 203 // want to expose destructors of core classes to embedders. We should |
86 // call reset() manually in destructors of classes with WebPrivatePtr | 204 // call reset() manually in destructors of classes with WebPrivatePtr |
87 // members. | 205 // members. |
88 BLINK_ASSERT(!m_ptr); | 206 BLINK_ASSERT(!m_storage); |
89 } | 207 } |
90 | 208 |
91 bool isNull() const { return !m_ptr; } | 209 bool isNull() const { return !m_storage; } |
92 | 210 |
93 #if INSIDE_BLINK | 211 #if INSIDE_BLINK |
94 WebPrivatePtr(const PassRefPtr<T>& prp) | 212 template<typename U> |
95 : m_ptr(prp.leakRef()) | 213 WebPrivatePtr(const U& ptr) |
214 : m_storage(0) | |
96 { | 215 { |
216 storage().assign(ptr); | |
97 } | 217 } |
98 | 218 |
99 void reset() | 219 void reset() { storage().release(); } |
100 { | |
101 assign(0); | |
102 } | |
103 | 220 |
104 WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other) | 221 WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other) |
105 { | 222 { |
106 T* p = other.m_ptr; | 223 storage().assign(other.storage()); |
107 if (p) | |
108 p->ref(); | |
109 assign(p); | |
110 return *this; | 224 return *this; |
111 } | 225 } |
112 | 226 |
113 WebPrivatePtr<T>& operator=(const PassRefPtr<T>& prp) | 227 WebPrivatePtr<T>& operator=(std::nullptr_t&) |
jamesr
2014/02/18 22:18:53
NAK on this - we can't expose std::nullptr_t throu
jamesr
2014/02/18 22:20:30
Ah - I missed that this was in the INSIDE_BLINK se
sof
2014/02/19 06:11:44
It will go away once https://codereview.chromium.o
| |
114 { | 228 { |
115 assign(prp.leakRef()); | 229 reset(); |
116 return *this; | 230 return *this; |
117 } | 231 } |
118 | 232 |
119 T* get() const | 233 template<typename U> |
234 WebPrivatePtr<T>& operator=(const U& ptr) | |
120 { | 235 { |
121 return m_ptr; | 236 storage().assign(ptr); |
237 return *this; | |
122 } | 238 } |
123 | 239 |
240 T* get() const { return storage().get(); } | |
241 | |
124 T* operator->() const | 242 T* operator->() const |
125 { | 243 { |
126 ASSERT(m_ptr); | 244 ASSERT(m_storage); |
127 return m_ptr; | 245 return get(); |
128 } | 246 } |
129 #endif | 247 #endif |
130 | 248 |
131 private: | 249 private: |
132 #if INSIDE_BLINK | 250 #if INSIDE_BLINK |
133 void assign(T* p) | 251 PtrStorage<T>& storage() { return PtrStorage<T>::fromSlot(&m_storage); } |
134 { | 252 const PtrStorage<T>& storage() const { return PtrStorage<T>::fromSlot(&m_sto rage); } |
135 // p is already ref'd for us by the caller | 253 #endif |
136 if (m_ptr) | 254 |
137 m_ptr->deref(); | 255 #if !INSIDE_BLINK |
138 m_ptr = p; | |
139 } | |
140 #else | |
141 // Disable the assignment operator; we define it above for when | 256 // Disable the assignment operator; we define it above for when |
142 // INSIDE_BLINK is set, but we need to make sure that it is not | 257 // INSIDE_BLINK is set, but we need to make sure that it is not |
143 // used outside there; the compiler-provided version won't handle reference | 258 // used outside there; the compiler-provided version won't handle reference |
144 // counting properly. | 259 // counting properly. |
145 WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other); | 260 WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other); |
146 #endif | 261 #endif |
147 // Disable the copy constructor; classes that contain a WebPrivatePtr | 262 // Disable the copy constructor; classes that contain a WebPrivatePtr |
148 // should implement their copy constructor using assign(). | 263 // should implement their copy constructor using assign(). |
149 WebPrivatePtr(const WebPrivatePtr<T>&); | 264 WebPrivatePtr(const WebPrivatePtr<T>&); |
150 | 265 |
151 T* m_ptr; | 266 void* m_storage; |
152 }; | 267 }; |
153 | 268 |
154 } // namespace blink | 269 } // namespace blink |
155 | 270 |
156 #endif | 271 #endif |
OLD | NEW |