[WK2] Small Caps font variant issue for Italic fonts
[framework/web/webkit-efl.git] / Source / WTF / wtf / RefCounted.h
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 // 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 {
37 public:
38     void ref()
39     {
40 #ifndef NDEBUG
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.
47         if (m_refCount == 1)
48             m_verifier.setShared(true);
49 #endif
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);
56         ++m_refCount;
57     }
58
59     bool hasOneRef() const
60     {
61         ASSERT(m_verifier.isSafeToUse());
62         ASSERT(!m_deletionHasBegun);
63         return m_refCount == 1;
64     }
65
66     int refCount() const
67     {
68         ASSERT(m_verifier.isSafeToUse());
69         return m_refCount;
70     }
71
72     void setMutexForVerifier(Mutex&);
73
74 #if HAVE(DISPATCH_H)
75     void setDispatchQueueForVerifier(dispatch_queue_t);
76 #endif
77
78     // Turns off verification. Use of this method is discouraged (instead extend
79     // ThreadRestrictionVerifier to verify your case).
80     // NB. It is necessary to call this in the constructor of many objects in
81     // JavaScriptCore, because JavaScriptCore objects may be used from multiple
82     // threads even if the reference counting is done in a racy manner. This is
83     // because a JSC instance may be used from multiple threads so long as all
84     // accesses into that instance are protected by a per-instance lock. It would
85     // be absolutely wrong to prohibit this pattern, and it would be a disastrous
86     // regression to require that the objects within that instance use a thread-
87     // safe version of reference counting.
88     void turnOffVerifier()
89     {
90 #ifndef NDEBUG
91         m_verifier.turnOffVerification();
92 #endif
93     }
94
95     void relaxAdoptionRequirement()
96     {
97 #ifndef NDEBUG
98         ASSERT(!m_deletionHasBegun);
99         ASSERT(m_adoptionIsRequired);
100         m_adoptionIsRequired = false;
101 #endif
102     }
103
104     // Helper for generating JIT code. Please do not use for non-JIT purposes.
105     const int* addressOfCount() const
106     {
107         return &m_refCount;
108     }
109
110 protected:
111     RefCountedBase()
112         : m_refCount(1)
113 #ifndef NDEBUG
114         , m_deletionHasBegun(false)
115         , m_adoptionIsRequired(true)
116 #endif
117     {
118     }
119
120     ~RefCountedBase()
121     {
122         ASSERT(m_deletionHasBegun);
123         ASSERT(!m_adoptionIsRequired);
124     }
125
126     // Returns whether the pointer should be freed or not.
127     bool derefBase()
128     {
129         ASSERT(m_verifier.isSafeToUse());
130         ASSERT(!m_deletionHasBegun);
131         ASSERT(!m_adoptionIsRequired);
132
133         ASSERT(m_refCount > 0);
134         if (m_refCount == 1) {
135 #ifndef NDEBUG
136             m_deletionHasBegun = true;
137 #endif
138             return true;
139         }
140
141         --m_refCount;
142 #ifndef NDEBUG
143         // Stop thread verification when the ref goes to 1 because it
144         // is safe to be passed to another thread at this point.
145         if (m_refCount == 1)
146             m_verifier.setShared(false);
147 #endif
148         return false;
149     }
150
151 #ifndef NDEBUG
152     bool deletionHasBegun() const
153     {
154         return m_deletionHasBegun;
155     }
156 #endif
157
158 private:
159
160 #ifndef NDEBUG
161     friend void adopted(RefCountedBase*);
162 #endif
163
164     int m_refCount;
165 #ifndef NDEBUG
166     bool m_deletionHasBegun;
167     bool m_adoptionIsRequired;
168     ThreadRestrictionVerifier m_verifier;
169 #endif
170 };
171
172 #ifndef NDEBUG
173
174 inline void adopted(RefCountedBase* object)
175 {
176     if (!object)
177         return;
178     ASSERT(!object->m_deletionHasBegun);
179     object->m_adoptionIsRequired = false;
180 }
181
182 #endif
183
184 template<typename T> class RefCounted : public RefCountedBase {
185     WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED;
186 public:
187     void deref()
188     {
189         if (derefBase())
190             delete static_cast<T*>(this);
191     }
192
193 protected:
194     RefCounted() { }
195     ~RefCounted()
196     {
197     }
198 };
199
200 template<typename T> class RefCountedCustomAllocated : public RefCountedBase {
201     WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated);
202
203 public:
204     void deref()
205     {
206         if (derefBase())
207             delete static_cast<T*>(this);
208     }
209
210 protected:
211     ~RefCountedCustomAllocated()
212     {
213     }
214 };
215
216 #ifdef NDEBUG
217 inline void RefCountedBase::setMutexForVerifier(Mutex&) { }
218 #else
219 inline void RefCountedBase::setMutexForVerifier(Mutex& mutex)
220 {
221     m_verifier.setMutexMode(mutex);
222 }
223 #endif
224
225 #if HAVE(DISPATCH_H)
226 #ifdef NDEBUG
227 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t) { }
228 #else
229 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t queue)
230 {
231     m_verifier.setDispatchQueueMode(queue);
232 }
233 #endif // NDEBUG
234 #endif // HAVE(DISPATCH_H)
235
236 } // namespace WTF
237
238 using WTF::RefCounted;
239 using WTF::RefCountedCustomAllocated;
240
241 #endif // RefCounted_h