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;
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;
88 WeakPtr(PassRefPtr<WeakReference<T> > ref) : m_ref(ref) { }
90 T* get() const { return m_ref ? m_ref->get() : 0; }
91 void clear() { m_ref.clear(); }
99 typedef RefPtr<WeakReference<T> > (WeakPtr::*UnspecifiedBoolType);
100 operator UnspecifiedBoolType() const { return get() ? &WeakPtr::m_ref : 0; }
103 RefPtr<WeakReference<T> > m_ref;
106 template<typename T, typename U> inline bool operator==(const WeakPtr<T>& a, const WeakPtr<U>& b)
108 return a.get() == b.get();
111 template<typename T, typename U> inline bool operator!=(const WeakPtr<T>& a, const WeakPtr<U>& b)
113 return a.get() != b.get();
117 class WeakPtrFactory {
118 WTF_MAKE_NONCOPYABLE(WeakPtrFactory<T>);
119 WTF_MAKE_FAST_ALLOCATED;
121 explicit WeakPtrFactory(T* ptr) : m_ref(WeakReference<T>::create(ptr)) { }
123 WeakPtrFactory(PassRefPtr<WeakReference<T> > ref, T* ptr)
129 ~WeakPtrFactory() { m_ref->clear(); }
131 // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called.
132 WeakPtr<T> createWeakPtr() { return WeakPtr<T>(m_ref); }
136 T* ptr = m_ref->get();
138 // We create a new WeakReference so that future calls to createWeakPtr() create nonzero WeakPtrs.
139 m_ref = WeakReference<T>::create(ptr);
143 RefPtr<WeakReference<T> > m_ref;
149 using WTF::WeakPtrFactory;
150 using WTF::WeakReference;