Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: Source/WTF/wtf/RefCounted.h

Issue 14238015: Move Source/WTF/wtf to Source/wtf (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 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/FastAllocBase.h>
26 #include <wtf/Noncopyable.h>
27 #include <wtf/OwnPtr.h>
28 #include <wtf/ThreadRestrictionVerifier.h>
29 #include <wtf/UnusedParam.h>
30
31 namespace WTF {
32
33 #ifdef NDEBUG
34 #define CHECK_REF_COUNTED_LIFECYCLE 0
35 #else
36 #define CHECK_REF_COUNTED_LIFECYCLE 1
37 #endif
38
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 RefCountedBase {
43 public:
44 void ref()
45 {
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 threa d
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 CrossThreadCopie r.h
52 // We should be able to add a "detachFromThread" method to make this exp licit.
53 if (m_refCount == 1)
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_deletionHasBegun);
60 ASSERT(!m_adoptionIsRequired);
61 #endif
62 ++m_refCount;
63 }
64
65 bool hasOneRef() const
66 {
67 #if CHECK_REF_COUNTED_LIFECYCLE
68 ASSERT(m_verifier.isSafeToUse());
69 ASSERT(!m_deletionHasBegun);
70 #endif
71 return m_refCount == 1;
72 }
73
74 int refCount() const
75 {
76 #if CHECK_REF_COUNTED_LIFECYCLE
77 ASSERT(m_verifier.isSafeToUse());
78 #endif
79 return m_refCount;
80 }
81
82 void setMutexForVerifier(Mutex&);
83
84 #if HAVE(DISPATCH_H)
85 void setDispatchQueueForVerifier(dispatch_queue_t);
86 #endif
87
88 // Turns off verification. Use of this method is discouraged (instead extend
89 // ThreadRestrictionVerifier to verify your case).
90 // NB. It is necessary to call this in the constructor of many objects in
91 // JavaScriptCore, because JavaScriptCore objects may be used from multiple
92 // threads even if the reference counting is done in a racy manner. This is
93 // because a JSC instance may be used from multiple threads so long as all
94 // accesses into that instance are protected by a per-instance lock. It woul d
95 // be absolutely wrong to prohibit this pattern, and it would be a disastrou s
96 // regression to require that the objects within that instance use a thread-
97 // safe version of reference counting.
98 void turnOffVerifier()
99 {
100 #if CHECK_REF_COUNTED_LIFECYCLE
101 m_verifier.turnOffVerification();
102 #endif
103 }
104
105 void relaxAdoptionRequirement()
106 {
107 #if CHECK_REF_COUNTED_LIFECYCLE
108 ASSERT(!m_deletionHasBegun);
109 ASSERT(m_adoptionIsRequired);
110 m_adoptionIsRequired = false;
111 #endif
112 }
113
114 // Helper for generating JIT code. Please do not use for non-JIT purposes.
115 const int* addressOfCount() const
116 {
117 return &m_refCount;
118 }
119
120 protected:
121 RefCountedBase()
122 : m_refCount(1)
123 #if CHECK_REF_COUNTED_LIFECYCLE
124 , m_deletionHasBegun(false)
125 , m_adoptionIsRequired(true)
126 #endif
127 {
128 }
129
130 ~RefCountedBase()
131 {
132 #if CHECK_REF_COUNTED_LIFECYCLE
133 ASSERT(m_deletionHasBegun);
134 ASSERT(!m_adoptionIsRequired);
135 #endif
136 }
137
138 // Returns whether the pointer should be freed or not.
139 bool derefBase()
140 {
141 #if CHECK_REF_COUNTED_LIFECYCLE
142 ASSERT(m_verifier.isSafeToUse());
143 ASSERT(!m_deletionHasBegun);
144 ASSERT(!m_adoptionIsRequired);
145 #endif
146
147 ASSERT(m_refCount > 0);
148 if (m_refCount == 1) {
149 #if CHECK_REF_COUNTED_LIFECYCLE
150 m_deletionHasBegun = true;
151 #endif
152 return true;
153 }
154
155 --m_refCount;
156 #if CHECK_REF_COUNTED_LIFECYCLE
157 // Stop thread verification when the ref goes to 1 because it
158 // is safe to be passed to another thread at this point.
159 if (m_refCount == 1)
160 m_verifier.setShared(false);
161 #endif
162 return false;
163 }
164
165 #if CHECK_REF_COUNTED_LIFECYCLE
166 bool deletionHasBegun() const
167 {
168 return m_deletionHasBegun;
169 }
170 #endif
171
172 private:
173
174 #if CHECK_REF_COUNTED_LIFECYCLE
175 friend void adopted(RefCountedBase*);
176 #endif
177
178 int m_refCount;
179 #if CHECK_REF_COUNTED_LIFECYCLE
180 bool m_deletionHasBegun;
181 bool m_adoptionIsRequired;
182 ThreadRestrictionVerifier m_verifier;
183 #endif
184 };
185
186 #if CHECK_REF_COUNTED_LIFECYCLE
187 inline void adopted(RefCountedBase* object)
188 {
189 if (!object)
190 return;
191 ASSERT(!object->m_deletionHasBegun);
192 object->m_adoptionIsRequired = false;
193 }
194 #endif
195
196 template<typename T> class RefCounted : public RefCountedBase {
197 WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED;
198 public:
199 void deref()
200 {
201 if (derefBase())
202 delete static_cast<T*>(this);
203 }
204
205 protected:
206 RefCounted() { }
207 ~RefCounted()
208 {
209 }
210 };
211
212 template<typename T> class RefCountedCustomAllocated : public RefCountedBase {
213 WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated);
214
215 public:
216 void deref()
217 {
218 if (derefBase())
219 delete static_cast<T*>(this);
220 }
221
222 protected:
223 ~RefCountedCustomAllocated()
224 {
225 }
226 };
227
228 #if CHECK_REF_COUNTED_LIFECYCLE
229 inline void RefCountedBase::setMutexForVerifier(Mutex& mutex)
230 {
231 m_verifier.setMutexMode(mutex);
232 }
233 #else
234 inline void RefCountedBase::setMutexForVerifier(Mutex&) { }
235 #endif
236
237 #if HAVE(DISPATCH_H)
238 #if CHECK_REF_COUNTED_LIFECYCLE
239 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t queue)
240 {
241 m_verifier.setDispatchQueueMode(queue);
242 }
243 #else
244 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t) { }
245 #endif
246 #endif // HAVE(DISPATCH_H)
247
248 } // namespace WTF
249
250 using WTF::RefCounted;
251 using WTF::RefCountedCustomAllocated;
252
253 #endif // RefCounted_h
OLDNEW
« no previous file with comments | « Source/WTF/wtf/RawPointer.h ('k') | Source/WTF/wtf/RefCountedArray.h » ('j') | Source/config.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698