Field3D
RefCount.h
Go to the documentation of this file.
1//----------------------------------------------------------------------------//
2
3/*
4 * Copyright (c) 2009 Sony Pictures Imageworks Inc
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution. Neither the name of Sony Pictures Imageworks nor the
18 * names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36//----------------------------------------------------------------------------//
37
42//----------------------------------------------------------------------------//
43
44#ifndef _INCLUDED_Field3D_REF_COUNT_H_
45#define _INCLUDED_Field3D_REF_COUNT_H_
46
47#define FIELD3D_USE_ATOMIC_COUNT
48
49//----------------------------------------------------------------------------//
50#include <boost/intrusive_ptr.hpp>
51
52#include <boost/shared_ptr.hpp>
53#include <boost/weak_ptr.hpp>
54
55#ifdef FIELD3D_USE_ATOMIC_COUNT
56#include <boost/detail/atomic_count.hpp>
57#else
58#include <boost/thread/mutex.hpp>
59#endif
60
61#include <string.h>
62#include "Traits.h"
63#include "ns.h"
64
66
67//----------------------------------------------------------------------------//
68// Field RTTI Replacement
69//----------------------------------------------------------------------------//
70
71#define DEFINE_CHECK_RTTI_CALL \
72 virtual bool checkRTTI(const char *typenameStr) \
73 { return matchRTTI(typenameStr); } \
74
75#define DEFINE_MATCH_RTTI_CALL \
76 bool matchRTTI(const char *typenameStr) \
77 { \
78 if (strcmp(typenameStr,staticClassType()) == 0) { \
79 return true; \
80 } \
81 return base::matchRTTI(typenameStr); \
82 } \
83
84#define DEFINE_FIELD_RTTI_CONCRETE_CLASS \
85 DEFINE_CHECK_RTTI_CALL \
86 DEFINE_MATCH_RTTI_CALL \
87
88#define DEFINE_FIELD_RTTI_ABSTRACT_CLASS \
89 DEFINE_MATCH_RTTI_CALL \
90
91//----------------------------------------------------------------------------//
92// null_deleter (for shared_ptr)
93//----------------------------------------------------------------------------//
94
99{
100 void operator()(void const *) const
101 { }
102};
103
104//----------------------------------------------------------------------------//
105
107{
108public:
109
110 // Typedefs ------------------------------------------------------------------
111
112 typedef boost::intrusive_ptr<RefBase> Ptr;
113 typedef boost::weak_ptr<RefBase> WeakPtr;
114
115 // Constructors --------------------------------------------------------------
116
119
121 : m_counter(0),
122 m_sharedPtr(this, null_deleter())
123 { }
124
129 : m_counter(0),
130 m_sharedPtr(this, null_deleter())
131 { }
132
134 RefBase& operator= (const RefBase&)
135 { return *this; }
136
138 virtual ~RefBase()
139 {}
140
142
143 // Reference counting --------------------------------------------------------
144
146 size_t refcnt()
147 { return m_counter; }
148
150 void ref() const
151 {
152#ifndef FIELD3D_USE_ATOMIC_COUNT
153 boost::mutex::scoped_lock lock(m_refMutex);
154#endif
155 ++m_counter;
156 }
157
159 void unref() const
160 {
161#ifndef FIELD3D_USE_ATOMIC_COUNT
162 boost::mutex::scoped_lock lock(m_refMutex);
163#endif
164 --m_counter;
165 // since we use intrusive_pointer no need
166 // to delete the object ourselves.
167 }
168
169 // Cache handling ------------------------------------------------------------
170
172 { return m_sharedPtr; }
173
174 // RTTI replacement ----------------------------------------------------------
175
186
189 virtual bool checkRTTI(const char *typenameStr) = 0;
190
193 bool matchRTTI(const char *typenameStr)
194 {
195 if (strcmp(staticClassType(), typenameStr) == 0)
196 return true;
197 return false;
198 }
199
200 static const char *staticClassType()
201 {
202 return "RefBase";
203 }
204
206
207private:
208
210#ifdef FIELD3D_USE_ATOMIC_COUNT
211 mutable boost::detail::atomic_count m_counter;
212#else
213 mutable long m_counter;
215 mutable boost::mutex m_refMutex;
216#endif
217
220 boost::shared_ptr<RefBase> m_sharedPtr;
221
222};
223
224//----------------------------------------------------------------------------//
225// Intrusive Pointer reference counting
226//----------------------------------------------------------------------------//
227
228inline void
230{
231 r->ref();
232}
233
234//----------------------------------------------------------------------------//
235
238inline void
240{
241 r->unref();
242
243 if (r->refcnt() == 0)
244 delete r;
245}
246
247//----------------------------------------------------------------------------//
248// field_dynamic_cast
249//----------------------------------------------------------------------------//
250
254template <class Field_T>
255typename Field_T::Ptr
257{
258 if (!field)
259 return NULL;
260
261 const char *tgtTypeString = Field_T::staticClassType();
262
263 if (field->checkRTTI(tgtTypeString)) {
264 return static_cast<Field_T*>(field.get());
265 } else {
266 return NULL;
267 }
268}
269
270//#define FIELD_DYNAMIC_CAST boost::dynamic_pointer_cast
271#define FIELD_DYNAMIC_CAST field_dynamic_cast
272
273//----------------------------------------------------------------------------//
274
276
277//----------------------------------------------------------------------------//
278
279#endif // Include guard
280
void intrusive_ptr_add_ref(RefBase *r)
Definition RefCount.h:229
void intrusive_ptr_release(RefBase *r)
Definition RefCount.h:239
bool matchRTTI(const char *typenameStr)
Performs a check to see if the given typename string matches this class' This needs to be implemented...
Definition RefCount.h:193
void ref() const
Used by boost::intrusive_pointer.
Definition RefCount.h:150
boost::intrusive_ptr< RefBase > Ptr
Definition RefCount.h:112
virtual ~RefBase()
Destructor.
Definition RefCount.h:138
boost::weak_ptr< RefBase > WeakPtr
Definition RefCount.h:113
WeakPtr weakPtr() const
Definition RefCount.h:171
virtual bool checkRTTI(const char *typenameStr)=0
This function is only implemented by concrete classes and triggers the actual RTTI check through matc...
boost::shared_ptr< RefBase > m_sharedPtr
For use by the FieldCache only: The shared pointer lets us see if this object is still alive.
Definition RefCount.h:220
size_t refcnt()
Used by boost::intrusive_pointer.
Definition RefCount.h:146
boost::detail::atomic_count m_counter
For boost intrusive pointer.
Definition RefCount.h:211
static const char * staticClassType()
Definition RefCount.h:200
void unref() const
Used by boost::intrusive_pointer.
Definition RefCount.h:159
RefBase(const RefBase &)
Copy constructor.
Definition RefCount.h:128
RefBase()
Definition RefCount.h:120
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
Definition RefCount.h:256
#define FIELD3D_API
Definition ns.h:77
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition ns.h:58
Used to let a shared pointer exist that doesn't delete anything. This is used by RefBase to hold a sh...
Definition RefCount.h:99
void operator()(void const *) const
Definition RefCount.h:100