OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Referenced.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 #ifndef OSG_REFERENCED
15 #define OSG_REFERENCED 1
16 
17 #include <osg/Export>
18 
19 #include <OpenThreads/ScopedLock>
20 #include <OpenThreads/Mutex>
21 #include <OpenThreads/Atomic>
22 
23 #if !defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
24 # define _OSG_REFERENCED_USE_ATOMIC_OPERATIONS
25 #endif
26 
27 namespace osg {
28 
29 // forward declare, declared after Referenced below.
30 class DeleteHandler;
31 class Observer;
32 class ObserverSet;
33 
35 template <typename T, T M()>
36 struct depends_on
37 {
38  depends_on() { M(); }
39 };
40 
43 {
44 
45  public:
46 
47 
48  Referenced();
49 
50  explicit Referenced(bool threadSafeRefUnref);
51 
52  Referenced(const Referenced&);
53 
54  inline Referenced& operator = (const Referenced&) { return *this; }
55 
57  virtual void setThreadSafeRefUnref(bool threadSafe);
58 
61 #if defined(_OSG_REFERENCED_USE_ATOMIC_OPERATIONS)
62  bool getThreadSafeRefUnref() const { return true; }
63 #else
64  bool getThreadSafeRefUnref() const { return _refMutex!=0; }
65 #endif
66 
68 #if defined(_OSG_REFERENCED_USE_ATOMIC_OPERATIONS)
69  OpenThreads::Mutex* getRefMutex() const { return getGlobalReferencedMutex(); }
70 #else
71  OpenThreads::Mutex* getRefMutex() const { return _refMutex; }
72 #endif
73 
75  static OpenThreads::Mutex* getGlobalReferencedMutex();
76 
79  inline int ref() const;
80 
85  inline int unref() const;
86 
93  int unref_nodelete() const;
94 
96  inline int referenceCount() const { return _refCount; }
97 
98 
101  {
102  #if defined(_OSG_REFERENCED_USE_ATOMIC_OPERATIONS)
103  return static_cast<ObserverSet*>(_observerSet.get());
104  #else
105  return static_cast<ObserverSet*>(_observerSet);
106  #endif
107  }
108 
110  ObserverSet* getOrCreateObserverSet() const;
111 
113  void addObserver(Observer* observer) const;
114 
116  void removeObserver(Observer* observer) const;
117 
118  public:
119 
121  static void setThreadSafeReferenceCounting(bool enableThreadSafeReferenceCounting);
122 
124  static bool getThreadSafeReferenceCounting();
125 
126  friend class DeleteHandler;
127 
130  static void setDeleteHandler(DeleteHandler* handler);
131 
133  static DeleteHandler* getDeleteHandler();
134 
135 
136  protected:
137 
138  virtual ~Referenced();
139 
140  void signalObserversAndDelete(bool signalDelete, bool doDelete) const;
141 
142  void deleteUsingDeleteHandler() const;
143 
144 #if defined(_OSG_REFERENCED_USE_ATOMIC_OPERATIONS)
146 
148 #else
149 
150  mutable OpenThreads::Mutex* _refMutex;
151 
152  mutable int _refCount;
153 
154  mutable void* _observerSet;
155 #endif
156 };
157 
158 inline int Referenced::ref() const
159 {
160 #if defined(_OSG_REFERENCED_USE_ATOMIC_OPERATIONS)
161  return ++_refCount;
162 #else
163  if (_refMutex)
164  {
166  return ++_refCount;
167  }
168  else
169  {
170  return ++_refCount;
171  }
172 #endif
173 }
174 
175 inline int Referenced::unref() const
176 {
177  int newRef;
178 #if defined(_OSG_REFERENCED_USE_ATOMIC_OPERATIONS)
179  newRef = --_refCount;
180  bool needDelete = (newRef == 0);
181 #else
182  bool needDelete = false;
183  if (_refMutex)
184  {
186  newRef = --_refCount;
187  needDelete = newRef==0;
188  }
189  else
190  {
191  newRef = --_refCount;
192  needDelete = newRef==0;
193  }
194 #endif
195 
196  if (needDelete)
197  {
198  signalObserversAndDelete(true,true);
199  }
200  return newRef;
201 }
202 
203 // intrusive_ptr_add_ref and intrusive_ptr_release allow
204 // use of osg Referenced classes with boost::intrusive_ptr
205 inline void intrusive_ptr_add_ref(Referenced* p) { p->ref(); }
206 inline void intrusive_ptr_release(Referenced* p) { p->unref(); }
207 
208 }
209 
210 #endif
#define OSG_EXPORT
Definition: Export.h:43
void intrusive_ptr_release(Referenced *p)
Definition: Referenced.h:206
This class provides an object-oriented thread mutex interface.
Definition: Mutex.h:31
int unref() const
Definition: Referenced.h:175
int ref() const
Definition: Referenced.h:158
void intrusive_ptr_add_ref(Referenced *p)
Definition: Referenced.h:205
OpenThreads::AtomicPtr _observerSet
Definition: Referenced.h:145
bool getThreadSafeRefUnref() const
Definition: Referenced.h:62
This class provides an atomic increment and decrement operation.
Definition: Atomic.h:48
int referenceCount() const
Definition: Referenced.h:96
This class provides an atomic pointer assignment using cas operations.
Definition: Atomic.h:83
OpenThreads::Atomic _refCount
Definition: Referenced.h:147
Definition: AlphaFunc.h:19
ObserverSet * getObserverSet() const
Definition: Referenced.h:100
OpenThreads::Mutex * getRefMutex() const
Definition: Referenced.h:69
void signalObserversAndDelete(bool signalDelete, bool doDelete) const