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 {
108 public:
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 
128  RefBase(const RefBase&)
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 
171  WeakPtr weakPtr() const
172  { return m_sharedPtr; }
173 
174  // RTTI replacement ----------------------------------------------------------
175 
184 
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 
207 private:
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 
228 inline void
230 {
231  r->ref();
232 }
233 
234 //----------------------------------------------------------------------------//
235 
238 inline void
240 {
241  r->unref();
242 
243  if (r->refcnt() == 0)
244  delete r;
245 }
246 
247 //----------------------------------------------------------------------------//
248 // field_dynamic_cast
249 //----------------------------------------------------------------------------//
250 
254 template <class Field_T>
255 typename 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 
FIELD3D_NAMESPACE_HEADER_CLOSE
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
RefBase::RefBase
RefBase(const RefBase &)
Copy constructor.
Definition: RefCount.h:128
RefBase::~RefBase
virtual ~RefBase()
Destructor.
Definition: RefCount.h:138
RefBase::RefBase
RefBase()
Definition: RefCount.h:120
RefBase::matchRTTI
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
intrusive_ptr_add_ref
void intrusive_ptr_add_ref(RefBase *r)
Definition: RefCount.h:229
RefBase::refcnt
size_t refcnt()
Used by boost::intrusive_pointer.
Definition: RefCount.h:146
null_deleter
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
RefBase::m_sharedPtr
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
ns.h
field_dynamic_cast
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
null_deleter::operator()
void operator()(void const *) const
Definition: RefCount.h:100
RefBase::weakPtr
WeakPtr weakPtr() const
Definition: RefCount.h:171
RefBase::ref
void ref() const
Used by boost::intrusive_pointer.
Definition: RefCount.h:150
Traits.h
RefBase::staticClassType
static const char * staticClassType()
Definition: RefCount.h:200
FIELD3D_API
#define FIELD3D_API
Definition: ns.h:77
FIELD3D_NAMESPACE_OPEN
Definition: FieldMapping.cpp:74
RefBase::WeakPtr
boost::weak_ptr< RefBase > WeakPtr
Definition: RefCount.h:113
RefBase
Definition: RefCount.h:107
intrusive_ptr_release
void intrusive_ptr_release(RefBase *r)
Definition: RefCount.h:239
RefBase::m_counter
boost::detail::atomic_count m_counter
For boost intrusive pointer.
Definition: RefCount.h:211
RefBase::unref
void unref() const
Used by boost::intrusive_pointer.
Definition: RefCount.h:159
RefBase::checkRTTI
virtual bool checkRTTI(const char *typenameStr)=0
This function is only implemented by concrete classes and triggers the actual RTTI check through matc...
RefBase::Ptr
boost::intrusive_ptr< RefBase > Ptr
Definition: RefCount.h:112