• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20 
21 #ifndef RefCounted_h
22 #define RefCounted_h
23 
24 #include <wtf/Assertions.h>
25 #include <wtf/Noncopyable.h>
26 
27 namespace WTF {
28 
29 // This base class holds the non-template methods and attributes.
30 // The RefCounted class inherits from it reducing the template bloat
31 // generated by the compiler (technique called template hoisting).
32 class RefCountedBase {
33 public:
ref()34     void ref()
35     {
36         ASSERT(!m_deletionHasBegun);
37         ++m_refCount;
38     }
39 
hasOneRef()40     bool hasOneRef() const
41     {
42         ASSERT(!m_deletionHasBegun);
43         return m_refCount == 1;
44     }
45 
refCount()46     int refCount() const
47     {
48         return m_refCount;
49     }
50 
51 protected:
RefCountedBase()52     RefCountedBase()
53         : m_refCount(1)
54 #ifndef NDEBUG
55         , m_deletionHasBegun(false)
56 #endif
57     {
58     }
59 
~RefCountedBase()60     ~RefCountedBase()
61     {
62     }
63 
64     // Returns whether the pointer should be freed or not.
derefBase()65     bool derefBase()
66     {
67         ASSERT(!m_deletionHasBegun);
68         ASSERT(m_refCount > 0);
69         if (m_refCount == 1) {
70 #ifndef NDEBUG
71             m_deletionHasBegun = true;
72 #endif
73             return true;
74         }
75 
76         --m_refCount;
77         return false;
78     }
79 
80     // Helper for generating JIT code. Please do not use for non-JIT purposes.
addressOfCount()81     int* addressOfCount()
82     {
83         return &m_refCount;
84     }
85 
86 #ifndef NDEBUG
deletionHasBegun()87     bool deletionHasBegun() const
88     {
89         return m_deletionHasBegun;
90     }
91 #endif
92 
93 private:
94     template<class T>
95     friend class CrossThreadRefCounted;
96 
97     int m_refCount;
98 #ifndef NDEBUG
99     bool m_deletionHasBegun;
100 #endif
101 };
102 
103 
104 template<class T> class RefCounted : public RefCountedBase, public Noncopyable {
105 public:
deref()106     void deref()
107     {
108         if (derefBase())
109             delete static_cast<T*>(this);
110     }
111 
112 protected:
~RefCounted()113     ~RefCounted()
114     {
115     }
116 };
117 
118 template<class T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated {
119 public:
deref()120     void deref()
121     {
122         if (derefBase())
123             delete static_cast<T*>(this);
124     }
125 
126 protected:
~RefCountedCustomAllocated()127     ~RefCountedCustomAllocated()
128     {
129     }
130 };
131 
132 } // namespace WTF
133 
134 using WTF::RefCounted;
135 using WTF::RefCountedCustomAllocated;
136 
137 #endif // RefCounted_h
138