Panda3D
 All Classes Functions Variables Enumerations
copyOnWritePointer.I
1 // Filename: copyOnWritePointer.I
2 // Created by: drose (09Apr07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: CopyOnWritePointer::Constructor
18 // Access: Public
19 // Description:
20 ////////////////////////////////////////////////////////////////////
21 INLINE CopyOnWritePointer::
22 CopyOnWritePointer(CopyOnWriteObject *object) :
23  _cow_object(object)
24 {
25  if (_cow_object != (CopyOnWriteObject *)NULL) {
26  _cow_object->cache_ref();
27  }
28 }
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: CopyOnWritePointer::Copy Constructor
32 // Access: Public
33 // Description:
34 ////////////////////////////////////////////////////////////////////
35 INLINE CopyOnWritePointer::
36 CopyOnWritePointer(const CopyOnWritePointer &copy) :
37  _cow_object(copy._cow_object)
38 {
39  if (_cow_object != (CopyOnWriteObject *)NULL) {
40  _cow_object->cache_ref();
41  }
42 }
43 
44 ////////////////////////////////////////////////////////////////////
45 // Function: CopyOnWritePointer::Copy Assignment Operator
46 // Access: Public
47 // Description:
48 ////////////////////////////////////////////////////////////////////
49 INLINE void CopyOnWritePointer::
50 operator = (const CopyOnWritePointer &copy) {
51  operator = (copy._cow_object);
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: CopyOnWritePointer::Assignment Operator
56 // Access: Public
57 // Description:
58 ////////////////////////////////////////////////////////////////////
59 INLINE void CopyOnWritePointer::
60 operator = (CopyOnWriteObject *object) {
61  if (_cow_object != object) {
62  if (_cow_object != (CopyOnWriteObject *)NULL) {
63  cache_unref_delete(_cow_object);
64  }
65  _cow_object = object;
66  if (_cow_object != (CopyOnWriteObject *)NULL) {
67  _cow_object->cache_ref();
68  }
69  }
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: CopyOnWritePointer::Destructor
74 // Access: Public
75 // Description:
76 ////////////////////////////////////////////////////////////////////
77 INLINE CopyOnWritePointer::
78 ~CopyOnWritePointer() {
79  if (_cow_object != (CopyOnWriteObject *)NULL) {
80  cache_unref_delete(_cow_object);
81  }
82 }
83 
84 #ifdef USE_MOVE_SEMANTICS
85 ////////////////////////////////////////////////////////////////////
86 // Function: CopyOnWritePointer::Move Constructor
87 // Access: Public
88 // Description:
89 ////////////////////////////////////////////////////////////////////
90 INLINE CopyOnWritePointer::
91 CopyOnWritePointer(CopyOnWritePointer &&move) NOEXCEPT :
92  _cow_object(move._cow_object)
93 {
94  // Steal the other's reference count.
95  move._cow_object = (CopyOnWriteObject *)NULL;
96 }
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: CopyOnWritePointer::Move Assignment Operator
100 // Access: Public
101 // Description:
102 ////////////////////////////////////////////////////////////////////
103 INLINE void CopyOnWritePointer::
104 operator = (CopyOnWritePointer &&move) NOEXCEPT {
105  // Protect against self-move-assignment.
106  if (move._cow_object != _cow_object) {
107  CopyOnWriteObject *old_object = _cow_object;
108  _cow_object = move._cow_object;
109  move._cow_object = NULL;
110 
111  if (old_object != (CopyOnWriteObject *)NULL) {
112  cache_unref_delete(old_object);
113  }
114  }
115 }
116 #endif // USE_MOVE_SEMANTICS
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: CopyOnWritePointer::operator ==
120 // Access: Public
121 // Description:
122 ////////////////////////////////////////////////////////////////////
123 INLINE bool CopyOnWritePointer::
124 operator == (const CopyOnWritePointer &other) const {
125  return _cow_object == other._cow_object;
126 }
127 
128 ////////////////////////////////////////////////////////////////////
129 // Function: CopyOnWritePointer::operator !=
130 // Access: Public
131 // Description:
132 ////////////////////////////////////////////////////////////////////
133 INLINE bool CopyOnWritePointer::
134 operator != (const CopyOnWritePointer &other) const {
135  return _cow_object != other._cow_object;
136 }
137 
138 ////////////////////////////////////////////////////////////////////
139 // Function: CopyOnWritePointer::operator <
140 // Access: Public
141 // Description:
142 ////////////////////////////////////////////////////////////////////
143 INLINE bool CopyOnWritePointer::
144 operator < (const CopyOnWritePointer &other) const {
145  return _cow_object < other._cow_object;
146 }
147 
148 #ifndef COW_THREADED
149 ////////////////////////////////////////////////////////////////////
150 // Function: CopyOnWritePointer::get_read_pointer
151 // Access: Public
152 // Description: Returns a pointer locked for read. Until this
153 // pointer dereferences, calls to get_write_pointer()
154 // will force a copy.
155 //
156 // This flavor of the method is written for the
157 // non-threaded case.
158 ////////////////////////////////////////////////////////////////////
161  return _cow_object;
162 }
163 #endif // COW_THREADED
164 
165 #ifndef COW_THREADED
166 ////////////////////////////////////////////////////////////////////
167 // Function: CopyOnWritePointer::get_write_pointer
168 // Access: Public
169 // Description: Returns a pointer locked for write. If another
170 // thread or threads already hold the pointer locked for
171 // read, then this will force a copy.
172 //
173 // Until this pointer dereferences, calls to
174 // get_read_pointer() or get_write_pointer() will block.
175 //
176 // This flavor of the method is written for the
177 // non-threaded case.
178 ////////////////////////////////////////////////////////////////////
181  if (_cow_object == (CopyOnWriteObject *)NULL) {
182  return NULL;
183  }
184  if (_cow_object->get_cache_ref_count() > 1) {
185  PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy();
186  cache_unref_delete(_cow_object);
187  _cow_object = new_object;
188  _cow_object->cache_ref();
189  }
190  return _cow_object;
191 }
192 #endif // COW_THREADED
193 
194 ////////////////////////////////////////////////////////////////////
195 // Function: CopyOnWritePointer::get_unsafe_pointer
196 // Access: Public
197 // Description: Returns an unlocked pointer that you can write to.
198 // This should only be used in very narrow circumstances
199 // in which you know that no other thread may be
200 // accessing the pointer at the same time.
201 ////////////////////////////////////////////////////////////////////
204  return _cow_object;
205 }
206 
207 ////////////////////////////////////////////////////////////////////
208 // Function: CopyOnWritePointer::is_null
209 // Access: Public
210 // Description: Returns true if the CopyOnWritePointer contains a
211 // NULL pointer, false otherwise.
212 ////////////////////////////////////////////////////////////////////
214 is_null() const {
215  return (_cow_object == (CopyOnWriteObject *)NULL);
216 }
217 
218 ////////////////////////////////////////////////////////////////////
219 // Function: CopyOnWritePointer::clear
220 // Access: Public
221 // Description: Sets the pointer to NULL.
222 ////////////////////////////////////////////////////////////////////
224 clear() {
225  if (_cow_object != (CopyOnWriteObject *)NULL) {
226  cache_unref_delete(_cow_object);
227  }
228  _cow_object = NULL;
229 }
230 
231 ////////////////////////////////////////////////////////////////////
232 // Function: CopyOnWritePointer::test_ref_count_integrity
233 // Access: Published
234 // Description: Does some easy checks to make sure that the reference
235 // count isn't completely bogus. Returns true if ok,
236 // false otherwise.
237 ////////////////////////////////////////////////////////////////////
238 INLINE bool CopyOnWritePointer::
240  nassertr(_cow_object != (CopyOnWriteObject *)NULL, false);
241  return _cow_object->test_ref_count_integrity();
242 }
243 
244 ////////////////////////////////////////////////////////////////////
245 // Function: CopyOnWritePointer::test_ref_count_nonzero
246 // Access: Published
247 // Description: Does some easy checks to make sure that the reference
248 // count isn't zero, or completely bogus. Returns true
249 // if ok, false otherwise.
250 ////////////////////////////////////////////////////////////////////
251 INLINE bool CopyOnWritePointer::
253  nassertr(_cow_object != (CopyOnWriteObject *)NULL, false);
254  return _cow_object->test_ref_count_nonzero();
255 }
256 
257 #ifndef CPPPARSER
258 ////////////////////////////////////////////////////////////////////
259 // Function: CopyOnWritePointerTo::Constructor
260 // Access: Public
261 // Description:
262 ////////////////////////////////////////////////////////////////////
263 template<class T>
265 CopyOnWritePointerTo(To *object) : CopyOnWritePointer(object) {
266 }
267 #endif // CPPPARSER
268 
269 #ifndef CPPPARSER
270 ////////////////////////////////////////////////////////////////////
271 // Function: CopyOnWritePointerTo::Copy Constructor
272 // Access: Public
273 // Description:
274 ////////////////////////////////////////////////////////////////////
275 template<class T>
278  CopyOnWritePointer(copy)
279 {
280 }
281 #endif // CPPPARSER
282 
283 #ifndef CPPPARSER
284 ////////////////////////////////////////////////////////////////////
285 // Function: CopyOnWritePointerTo::Copy Assignment Operator
286 // Access: Public
287 // Description:
288 ////////////////////////////////////////////////////////////////////
289 template<class T>
290 INLINE void CopyOnWritePointerTo<T>::
292  CopyOnWritePointer::operator = (copy);
293 }
294 #endif // CPPPARSER
295 
296 #ifndef CPPPARSER
297 ////////////////////////////////////////////////////////////////////
298 // Function: CopyOnWritePointer::Assignment Operator
299 // Access: Public
300 // Description:
301 ////////////////////////////////////////////////////////////////////
302 template<class T>
303 INLINE void CopyOnWritePointerTo<T>::
304 operator = (To *object) {
305  CopyOnWritePointer::operator = (object);
306 }
307 #endif // CPPPARSER
308 
309 #ifdef USE_MOVE_SEMANTICS
310 #ifndef CPPPARSER
311 ////////////////////////////////////////////////////////////////////
312 // Function: CopyOnWritePointerTo::Move Constructor
313 // Access: Public
314 // Description:
315 ////////////////////////////////////////////////////////////////////
316 template<class T>
320 {
321 }
322 #endif // CPPPARSER
323 
324 #ifndef CPPPARSER
325 ////////////////////////////////////////////////////////////////////
326 // Function: CopyOnWritePointerTo::Move Assignment Operator
327 // Access: Public
328 // Description:
329 ////////////////////////////////////////////////////////////////////
330 template<class T>
331 INLINE void CopyOnWritePointerTo<T>::
332 operator = (CopyOnWritePointerTo<T> &&move) NOEXCEPT {
333  CopyOnWritePointer::operator = ((CopyOnWritePointer &&)move);
334 }
335 #endif // CPPPARSER
336 #endif // USE_MOVE_SEMANTICS
337 
338 #ifndef CPPPARSER
339 #ifdef COW_THREADED
340 ////////////////////////////////////////////////////////////////////
341 // Function: CopyOnWritePointerTo::get_read_pointer
342 // Access: Public
343 // Description: See CopyOnWritePointer::get_read_pointer().
344 ////////////////////////////////////////////////////////////////////
345 template<class T>
346 INLINE CPT(TYPENAME CopyOnWritePointerTo<T>::To) CopyOnWritePointerTo<T>::
347 get_read_pointer() const {
348  return (const To *)(CopyOnWritePointer::get_read_pointer().p());
349 }
350 #else // COW_THREADED
351 ////////////////////////////////////////////////////////////////////
352 // Function: CopyOnWritePointerTo::get_read_pointer
353 // Access: Public
354 // Description: See CopyOnWritePointer::get_read_pointer().
355 ////////////////////////////////////////////////////////////////////
356 template<class T>
357 INLINE const TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>::
359  return (const To *)CopyOnWritePointer::get_read_pointer();
360 }
361 #endif // COW_THREADED
362 #endif // CPPPARSER
363 
364 #ifndef CPPPARSER
365 #ifdef COW_THREADED
366 ////////////////////////////////////////////////////////////////////
367 // Function: CopyOnWritePointerTo::get_write_pointer
368 // Access: Public
369 // Description: See CopyOnWritePointer::get_write_pointer().
370 ////////////////////////////////////////////////////////////////////
371 template<class T>
372 INLINE PT(TYPENAME CopyOnWritePointerTo<T>::To) CopyOnWritePointerTo<T>::
374  return (To *)(CopyOnWritePointer::get_write_pointer().p());
375 }
376 #else // COW_THREADED
377 ////////////////////////////////////////////////////////////////////
378 // Function: CopyOnWritePointerTo::get_write_pointer
379 // Access: Public
380 // Description: See CopyOnWritePointer::get_write_pointer().
381 ////////////////////////////////////////////////////////////////////
382 template<class T>
383 INLINE TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>::
386 }
387 #endif // COW_THREADED
388 #endif // CPPPARSER
389 
390 #ifndef CPPPARSER
391 ////////////////////////////////////////////////////////////////////
392 // Function: CopyOnWritePointerTo::get_unsafe_pointer
393 // Access: Public
394 // Description: See CopyOnWritePointer::get_unsafe_pointer().
395 ////////////////////////////////////////////////////////////////////
396 template<class T>
397 INLINE TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>::
400 }
401 #endif // CPPPARSER
A template wrapper around the above class, mainly to handle the little typecasting niceties...
void clear()
Sets the pointer to NULL.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn&#39;t completely bogus.
To * get_write_pointer()
See CopyOnWritePointer::get_write_pointer().
const CopyOnWriteObject * get_read_pointer() const
Returns a pointer locked for read.
int get_cache_ref_count() const
Returns the current reference count.
CopyOnWriteObject * get_write_pointer()
Returns a pointer locked for write.
bool test_ref_count_nonzero() const
Does some easy checks to make sure that the reference count isn&#39;t zero, or completely bogus...
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
bool is_null() const
Returns true if the CopyOnWritePointer contains a NULL pointer, false otherwise.
To * get_unsafe_pointer()
See CopyOnWritePointer::get_unsafe_pointer().
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
This safely stores the primary, owned pointer to a CopyOnWriteObject.
const To * get_read_pointer() const
See CopyOnWritePointer::get_read_pointer().
bool test_ref_count_nonzero() const
Does some easy checks to make sure that the reference count isn&#39;t zero, or completely bogus...
CopyOnWriteObject * get_unsafe_pointer()
Returns an unlocked pointer that you can write to.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn&#39;t completely bogus.