2 * Copyright (C) 2013 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
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "wtf/Noncopyable.h"
30 #include "wtf/PassRefPtr.h"
31 #include "wtf/RefPtr.h"
32 #include "wtf/ThreadSafeRefCounted.h"
33 #include "wtf/Threading.h"
38 class WeakReference
: public ThreadSafeRefCounted
<WeakReference
<T
>> {
39 WTF_MAKE_NONCOPYABLE(WeakReference
<T
>);
40 WTF_MAKE_FAST_ALLOCATED(WeakReference
);
42 static PassRefPtr
<WeakReference
<T
>> create(T
* ptr
) { return adoptRef(new WeakReference(ptr
)); }
43 static PassRefPtr
<WeakReference
<T
>> createUnbound() { return adoptRef(new WeakReference()); }
47 ASSERT(m_boundThread
== currentThread());
53 ASSERT(m_boundThread
== currentThread());
61 m_boundThread
= currentThread();
67 WeakReference() : m_ptr(0) { }
69 explicit WeakReference(T
* ptr
)
72 , m_boundThread(currentThread())
79 ThreadIdentifier m_boundThread
;
85 WTF_MAKE_FAST_ALLOCATED(WeakPtr
);
88 WeakPtr(std::nullptr_t
) { }
89 WeakPtr(PassRefPtr
<WeakReference
<T
>> ref
) : m_ref(ref
) { }
91 T
* get() const { return m_ref
? m_ref
->get() : 0; }
92 void clear() { m_ref
.clear(); }
100 typedef RefPtr
<WeakReference
<T
>> (WeakPtr::*UnspecifiedBoolType
);
101 operator UnspecifiedBoolType() const { return get() ? &WeakPtr::m_ref
: 0; }
104 RefPtr
<WeakReference
<T
>> m_ref
;
107 template<typename T
, typename U
> inline bool operator==(const WeakPtr
<T
>& a
, const WeakPtr
<U
>& b
)
109 return a
.get() == b
.get();
112 template<typename T
, typename U
> inline bool operator!=(const WeakPtr
<T
>& a
, const WeakPtr
<U
>& b
)
114 return a
.get() != b
.get();
118 class WeakPtrFactory
{
119 WTF_MAKE_NONCOPYABLE(WeakPtrFactory
<T
>);
120 WTF_MAKE_FAST_ALLOCATED(WeakPtrFactory
);
122 explicit WeakPtrFactory(T
* ptr
) : m_ref(WeakReference
<T
>::create(ptr
)) { }
124 WeakPtrFactory(PassRefPtr
<WeakReference
<T
>> ref
, T
* ptr
)
130 ~WeakPtrFactory() { m_ref
->clear(); }
132 // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called.
133 WeakPtr
<T
> createWeakPtr() { return WeakPtr
<T
>(m_ref
); }
137 T
* ptr
= m_ref
->get();
139 // We create a new WeakReference so that future calls to createWeakPtr() create nonzero WeakPtrs.
140 m_ref
= WeakReference
<T
>::create(ptr
);
143 bool hasWeakPtrs() const
145 return m_ref
->refCount() > 1;
149 RefPtr
<WeakReference
<T
>> m_ref
;
155 using WTF::WeakPtrFactory
;
156 using WTF::WeakReference
;