2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
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.
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.
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.
24 #include "wtf/Assertions.h"
25 #include "wtf/FastAllocBase.h"
26 #include "wtf/InstanceCounter.h"
27 #include "wtf/Noncopyable.h"
28 #include "wtf/WTFExport.h"
31 #define CHECK_REF_COUNTED_LIFECYCLE 1
32 #include "wtf/ThreadRestrictionVerifier.h"
34 #define CHECK_REF_COUNTED_LIFECYCLE 0
39 // This base class holds the non-template methods and attributes.
40 // The RefCounted class inherits from it reducing the template bloat
41 // generated by the compiler (technique called template hoisting).
42 class WTF_EXPORT RefCountedBase
{
46 #if CHECK_REF_COUNTED_LIFECYCLE
47 // Start thread verification as soon as the ref count gets to 2. This
48 // heuristic reflects the fact that items are often created on one thread
49 // and then given to another thread to be used.
50 // FIXME: Make this restriction tigher. Especially as we move to more
51 // common methods for sharing items across threads like CrossThreadCopier.h
52 // We should be able to add a "detachFromThread" method to make this explicit.
54 m_verifier
.setShared(true);
55 // If this assert fires, it either indicates a thread safety issue or
56 // that the verification needs to change. See ThreadRestrictionVerifier for
57 // the different modes.
58 ASSERT(m_verifier
.isSafeToUse());
59 ASSERT(!m_adoptionIsRequired
);
61 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun
);
65 bool hasOneRef() const
67 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun
);
68 #if CHECK_REF_COUNTED_LIFECYCLE
69 ASSERT(m_verifier
.isSafeToUse());
71 return m_refCount
== 1;
76 #if CHECK_REF_COUNTED_LIFECYCLE
77 ASSERT(m_verifier
.isSafeToUse());
85 #if ENABLE(SECURITY_ASSERT)
86 , m_deletionHasBegun(false)
88 #if CHECK_REF_COUNTED_LIFECYCLE
89 , m_adoptionIsRequired(true)
96 ASSERT_WITH_SECURITY_IMPLICATION(m_deletionHasBegun
);
97 #if CHECK_REF_COUNTED_LIFECYCLE
98 ASSERT(!m_adoptionIsRequired
);
102 // Returns whether the pointer should be freed or not.
105 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun
);
106 #if CHECK_REF_COUNTED_LIFECYCLE
107 ASSERT(m_verifier
.isSafeToUse());
108 ASSERT(!m_adoptionIsRequired
);
111 ASSERT(m_refCount
> 0);
114 #if ENABLE(SECURITY_ASSERT)
115 m_deletionHasBegun
= true;
120 #if CHECK_REF_COUNTED_LIFECYCLE
121 // Stop thread verification when the ref goes to 1 because it
122 // is safe to be passed to another thread at this point.
124 m_verifier
.setShared(false);
129 #if CHECK_REF_COUNTED_LIFECYCLE
130 bool deletionHasBegun() const
132 return m_deletionHasBegun
;
138 #if CHECK_REF_COUNTED_LIFECYCLE || ENABLE(SECURITY_ASSERT)
139 friend void adopted(RefCountedBase
*);
143 #if ENABLE(SECURITY_ASSERT)
144 bool m_deletionHasBegun
;
146 #if CHECK_REF_COUNTED_LIFECYCLE
147 bool m_adoptionIsRequired
;
148 ThreadRestrictionVerifier m_verifier
;
152 #if CHECK_REF_COUNTED_LIFECYCLE || ENABLE(SECURITY_ASSERT)
153 inline void adopted(RefCountedBase
* object
)
157 ASSERT_WITH_SECURITY_IMPLICATION(!object
->m_deletionHasBegun
);
158 #if CHECK_REF_COUNTED_LIFECYCLE
159 object
->m_adoptionIsRequired
= false;
164 template<typename T
> class RefCounted
: public RefCountedBase
{
165 WTF_MAKE_NONCOPYABLE(RefCounted
);
166 WTF_MAKE_FAST_ALLOCATED(RefCounted
);
172 delete static_cast<T
*>(this);
176 #ifdef ENABLE_INSTANCE_COUNTER
179 incrementInstanceCount
<T
>(static_cast<T
*>(this));
184 decrementInstanceCount
<T
>(static_cast<T
*>(this));
195 using WTF::RefCounted
;
197 #endif // RefCounted_h