2 * Copyright (C) 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 WebPrivatePtr_h
32 #define WebPrivatePtr_h
34 #include "WebCommon.h"
37 #include "platform/heap/Handle.h"
38 #include "wtf/PassRefPtr.h"
39 #include "wtf/TypeTraits.h"
43 template<class T
> class ThreadSafeRefCounted
;
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
51 enum WebPrivatePtrDestruction
{
52 WebPrivatePtrDestructionSameThread
,
53 WebPrivatePtrDestructionCrossThread
,
57 enum LifetimeManagementType
{
59 GarbageCollectedLifetime
,
60 RefCountedGarbageCollectedLifetime
65 static const bool isGarbageCollected
= WTF::IsSubclassOfTemplate
<T
, GarbageCollected
>::value
|| IsGarbageCollectedMixin
<T
>::value
;
66 static const bool isRefCountedGarbageCollected
= WTF::IsSubclassOfTemplate
<T
, RefCountedGarbageCollected
>::value
;
68 static const LifetimeManagementType value
=
69 !isGarbageCollected
? RefCountedLifetime
:
70 isRefCountedGarbageCollected
? RefCountedGarbageCollectedLifetime
: GarbageCollectedLifetime
;
73 template<typename T
, WebPrivatePtrDestruction crossThreadDestruction
, LifetimeManagementType lifetime
>
76 template<typename T
, WebPrivatePtrDestruction crossThreadDestruction
>
77 class PtrStorageImpl
<T
, crossThreadDestruction
, RefCountedLifetime
> {
79 typedef PassRefPtr
<T
> BlinkPtrType
;
81 void assign(const BlinkPtrType
& val
)
83 static_assert(crossThreadDestruction
== WebPrivatePtrDestructionSameThread
|| WTF::IsSubclassOfTemplate
<T
, WTF::ThreadSafeRefCounted
>::value
, "Cross thread destructible class must derive from ThreadSafeRefCounted<>");
85 m_ptr
= val
.leakRef();
88 void assign(const PtrStorageImpl
& other
)
92 WTF::refIfNotNull(val
);
96 void moveFrom(PtrStorageImpl
& other
)
103 T
* get() const { return m_ptr
; }
107 WTF::derefIfNotNull(m_ptr
);
115 template <typename T
, WebPrivatePtrDestruction
>
116 struct WebPrivatePtrPersistentStorageType
{
118 using Type
= Persistent
<T
>;
121 template <typename T
>
122 struct WebPrivatePtrPersistentStorageType
<T
, WebPrivatePtrDestructionCrossThread
> {
124 using Type
= CrossThreadPersistent
<T
>;
127 template<typename T
, WebPrivatePtrDestruction crossThreadDestruction
>
128 class PtrStorageImpl
<T
, crossThreadDestruction
, GarbageCollectedLifetime
> {
130 void assign(const RawPtr
<T
>& val
)
138 m_handle
= new (typename WebPrivatePtrPersistentStorageType
<T
, crossThreadDestruction
>::Type
)();
143 void assign(T
* ptr
) { assign(RawPtr
<T
>(ptr
)); }
144 template<typename U
> void assign(const RawPtr
<U
>& val
) { assign(RawPtr
<T
>(val
)); }
146 void assign(const PtrStorageImpl
& other
) { assign(other
.get()); }
148 void moveFrom(PtrStorageImpl
& other
)
151 m_handle
= other
.m_handle
;
155 T
* get() const { return m_handle
? m_handle
->get() : 0; }
164 typename WebPrivatePtrPersistentStorageType
<T
, crossThreadDestruction
>::Type
* m_handle
;
167 template<typename T
, WebPrivatePtrDestruction crossThreadDestruction
>
168 class PtrStorageImpl
<T
, crossThreadDestruction
, RefCountedGarbageCollectedLifetime
> : public PtrStorageImpl
<T
, crossThreadDestruction
, GarbageCollectedLifetime
> {
170 void assign(const PassRefPtrWillBeRawPtr
<T
>& val
) { PtrStorageImpl
<T
, crossThreadDestruction
, GarbageCollectedLifetime
>::assign(val
.get()); }
172 void assign(const PtrStorageImpl
& other
) { PtrStorageImpl
<T
, crossThreadDestruction
, GarbageCollectedLifetime
>::assign(other
.get()); }
175 template<typename T
, WebPrivatePtrDestruction crossThreadDestruction
>
176 class PtrStorage
: public PtrStorageImpl
<T
, crossThreadDestruction
, LifetimeOf
<T
>::value
> {
178 static PtrStorage
& fromSlot(void** slot
)
180 static_assert(sizeof(PtrStorage
) == sizeof(void*), "PtrStorage must be the size of a pointer");
181 return *reinterpret_cast<PtrStorage
*>(slot
);
184 static const PtrStorage
& fromSlot(void* const* slot
)
186 static_assert(sizeof(PtrStorage
) == sizeof(void*), "PtrStorage must be the size of a pointer");
187 return *reinterpret_cast<const PtrStorage
*>(slot
);
191 // Prevent construction via normal means.
193 PtrStorage(const PtrStorage
&);
197 // This class is an implementation detail of the Blink API. It exists to help
198 // simplify the implementation of Blink interfaces that merely wrap a reference
199 // counted WebCore class.
201 // A typical implementation of a class which uses WebPrivatePtr might look like
205 // BLINK_EXPORT ~WebFoo();
207 // WebFoo(const WebFoo& other) { assign(other); }
208 // WebFoo& operator=(const WebFoo& other)
213 // BLINK_EXPORT void assign(const WebFoo&); // Implemented in the body.
215 // // Methods that are exposed to Chromium and which are specific to
216 // // WebFoo go here.
217 // BLINK_EXPORT doWebFooThing();
219 // // Methods that are used only by other Blink classes should only be
220 // // declared when INSIDE_BLINK is set.
222 // WebFoo(const WTF::PassRefPtr<Foo>&);
226 // WebPrivatePtr<Foo> m_private;
230 // WebFoo::~WebFoo() { m_private.reset(); }
231 // void WebFoo::assign(const WebFoo& other) { ... }
233 template <typename T
, WebPrivatePtrDestruction crossThreadDestruction
= WebPrivatePtrDestructionSameThread
>
234 class WebPrivatePtr
{
236 WebPrivatePtr() : m_storage(0) { }
239 // 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
241 // call reset() manually in destructors of classes with WebPrivatePtr
243 BLINK_ASSERT(!m_storage
);
246 bool isNull() const { return !m_storage
; }
250 WebPrivatePtr(const U
& ptr
)
253 storage().assign(ptr
);
256 void reset() { storage().release(); }
258 WebPrivatePtr
& operator=(const WebPrivatePtr
& other
)
260 storage().assign(other
.storage());
264 void moveFrom(WebPrivatePtr
& other
)
266 storage().moveFrom(other
.storage());
271 WebPrivatePtr
& operator=(const U
& ptr
)
273 storage().assign(ptr
);
277 T
* get() const { return storage().get(); }
285 T
* operator->() const
294 PtrStorage
<T
, crossThreadDestruction
>& storage() { return PtrStorage
<T
, crossThreadDestruction
>::fromSlot(&m_storage
); }
295 const PtrStorage
<T
, crossThreadDestruction
>& storage() const { return PtrStorage
<T
, crossThreadDestruction
>::fromSlot(&m_storage
); }
299 // 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
301 // used outside there; the compiler-provided version won't handle reference
302 // counting properly.
303 WebPrivatePtr
& operator=(const WebPrivatePtr
& other
);
305 // Disable the copy constructor; classes that contain a WebPrivatePtr
306 // should implement their copy constructor using assign().
307 WebPrivatePtr(const WebPrivatePtr
&);