Generalize DocumentWeakReference into WTF::WeakPtr
[WebKit-https.git] / Source / WTF / wtf / WeakPtr.h
1 /*
2  * Copyright (C) 2013 Google, Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25
26 #ifndef WTF_WeakPtr_h
27 #define WTF_WeakPtr_h
28
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>
34
35 namespace WTF {
36
37 namespace Internal {
38
39 template<typename T>
40 class WeakReference : public ThreadSafeRefCounted<WeakReference<T> > {
41     WTF_MAKE_NONCOPYABLE(WeakReference<T>);
42     WTF_MAKE_FAST_ALLOCATED;
43 public:
44     static PassRefPtr<WeakReference<T> > create(T* ptr) { return adoptRef(new WeakReference(ptr)); }
45
46     T* get() const
47     {
48         ASSERT(m_boundThread == currentThread());
49         return m_ptr;
50     }
51
52     void clear()
53     {
54         ASSERT(m_boundThread == currentThread());
55         m_ptr = 0;
56     }
57
58 private:
59     explicit WeakReference(T* ptr)
60         : m_ptr(ptr)
61 #ifndef NDEBUG
62         , m_boundThread(currentThread())
63 #endif
64     {
65     }
66
67     T* m_ptr;
68 #ifndef NDEBUG
69     ThreadIdentifier m_boundThread;
70 #endif
71 };
72
73 }
74
75 template<typename T>
76 class WeakPtr {
77     WTF_MAKE_FAST_ALLOCATED;
78 public:
79     WeakPtr() { }
80     WeakPtr(PassRefPtr<Internal::WeakReference<T> > ref) : m_ref(ref) { }
81
82     T* get() const { return m_ref->get(); }
83
84 private:
85     RefPtr<Internal::WeakReference<T> > m_ref;
86 };
87
88 template<typename T>
89 class WeakPtrFactory {
90     WTF_MAKE_NONCOPYABLE(WeakPtrFactory<T>);
91     WTF_MAKE_FAST_ALLOCATED;
92 public:
93     explicit WeakPtrFactory(T* ptr) { m_ref = Internal::WeakReference<T>::create(ptr); }
94     ~WeakPtrFactory() { m_ref->clear(); }
95
96     // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called.
97     WeakPtr<T> createWeakPtr() { return WeakPtr<T>(m_ref); }
98
99 private:
100     RefPtr<Internal::WeakReference<T> > m_ref;
101 };
102
103 } // namespace WTF
104
105 using WTF::WeakPtr;
106 using WTF::WeakPtrFactory;
107
108 #endif