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 "Assertions.h"
25 #include "FastAllocBase.h"
26 #include "ThreadRestrictionVerifier.h"
27 #include "Noncopyable.h"
29 #include "UnusedParam.h"
33 // This base class holds the non-template methods and attributes.
34 // The RefCounted class inherits from it reducing the template bloat
35 // generated by the compiler (technique called template hoisting).
36 class RefCountedBase {
41 // Start thread verification as soon as the ref count gets to 2. This
42 // heuristic reflects the fact that items are often created on one thread
43 // and then given to another thread to be used.
44 // FIXME: Make this restriction tigher. Especially as we move to more
45 // common methods for sharing items across threads like CrossThreadCopier.h
46 // We should be able to add a "detachFromThread" method to make this explicit.
48 m_verifier.setShared(true);
50 // If this assert fires, it either indicates a thread safety issue or
51 // that the verification needs to change. See ThreadRestrictionVerifier for
52 // the different modes.
53 ASSERT(m_verifier.isSafeToUse());
54 ASSERT(!m_deletionHasBegun);
55 ASSERT(!m_adoptionIsRequired);
59 bool hasOneRef() const
61 ASSERT(m_verifier.isSafeToUse());
62 ASSERT(!m_deletionHasBegun);
63 return m_refCount == 1;
68 ASSERT(m_verifier.isSafeToUse());
72 void setMutexForVerifier(Mutex&);
75 void setDispatchQueueForVerifier(dispatch_queue_t);
78 // Turns off verification. Use of this method is discouraged (instead extend
79 // ThreadRestrictionVerifier to verify your case).
80 // FIXME: remove this method.
81 void deprecatedTurnOffVerifier()
84 m_verifier.turnOffVerification();
88 void relaxAdoptionRequirement()
91 ASSERT(!m_deletionHasBegun);
92 ASSERT(m_adoptionIsRequired);
93 m_adoptionIsRequired = false;
97 // Helper for generating JIT code. Please do not use for non-JIT purposes.
98 const int* addressOfCount() const
107 , m_deletionHasBegun(false)
108 , m_adoptionIsRequired(true)
115 ASSERT(m_deletionHasBegun);
116 ASSERT(!m_adoptionIsRequired);
119 // Returns whether the pointer should be freed or not.
122 ASSERT(m_verifier.isSafeToUse());
123 ASSERT(!m_deletionHasBegun);
124 ASSERT(!m_adoptionIsRequired);
126 ASSERT(m_refCount > 0);
127 if (m_refCount == 1) {
129 m_deletionHasBegun = true;
136 // Stop thread verification when the ref goes to 1 because it
137 // is safe to be passed to another thread at this point.
139 m_verifier.setShared(false);
145 bool deletionHasBegun() const
147 return m_deletionHasBegun;
154 friend void adopted(RefCountedBase*);
159 bool m_deletionHasBegun;
160 bool m_adoptionIsRequired;
161 ThreadRestrictionVerifier m_verifier;
167 inline void adopted(RefCountedBase* object)
171 ASSERT(!object->m_deletionHasBegun);
172 object->m_adoptionIsRequired = false;
177 template<typename T> class RefCounted : public RefCountedBase {
178 WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED;
183 delete static_cast<T*>(this);
193 template<typename T> class RefCountedCustomAllocated : public RefCountedBase {
194 WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated);
200 delete static_cast<T*>(this);
204 ~RefCountedCustomAllocated()
210 inline void RefCountedBase::setMutexForVerifier(Mutex&) { }
212 inline void RefCountedBase::setMutexForVerifier(Mutex& mutex)
214 m_verifier.setMutexMode(mutex);
220 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t) { }
222 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t queue)
224 m_verifier.setDispatchQueueMode(queue);
227 #endif // HAVE(DISPATCH_H)
231 using WTF::RefCounted;
232 using WTF::RefCountedCustomAllocated;
234 #endif // RefCounted_h