Panda3D
threadSafePointerToBase.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file threadSafePointerToBase.I
10  * @author drose
11  * @date 2006-04-28
12  */
13 
14 /**
15  *
16  */
17 template<class T>
19 ThreadSafePointerToBase(To *ptr) {
20  reassign(ptr);
21 }
22 
23 /**
24  *
25  */
26 template<class T>
29  reassign(copy);
30 }
31 
32 /**
33  *
34  */
35 template<class T>
38  reassign(nullptr);
39 }
40 
41 /**
42  * This is the main work of the ThreadSafePointerTo family. When the pointer
43  * is reassigned, decrement the old reference count and increment the new one.
44  */
45 template<class T>
47 reassign(To *ptr) {
48  To *old_ptr = (To *)AtomicAdjust::get_ptr(_void_ptr);
49  if (ptr == old_ptr) {
50  return;
51  }
52 
53 #ifdef HAVE_THREADS
54  void *orig_ptr = AtomicAdjust::compare_and_exchange_ptr(_void_ptr, old_ptr, ptr);
55  while (orig_ptr != old_ptr) {
56  // Some other thread assigned it first. Try again.
57  old_ptr = (To *)AtomicAdjust::get_ptr(_void_ptr);
58  if (ptr == old_ptr) {
59  return;
60  }
61 
62  orig_ptr = AtomicAdjust::compare_and_exchange_ptr(_void_ptr, old_ptr, ptr);
63  }
64 #else // HAVE_THREADS
65  _void_ptr = ptr;
66 #endif // HAVE_THREADS
67 
68  if (ptr != nullptr) {
69  ptr->ref();
70 #ifdef DO_MEMORY_USAGE
72  update_type(ptr);
73  }
74 #endif
75  }
76 
77  // Now delete the old pointer.
78  if (old_ptr != nullptr) {
79  unref_delete(old_ptr);
80  }
81 }
82 
83 /**
84  *
85  */
86 template<class T>
89  reassign((To *)copy._void_ptr);
90 }
91 
92 /**
93  * Ensures that the MemoryUsage record for the pointer has the right type of
94  * object, if we know the type ourselves.
95  */
96 template<class T>
98 update_type(To *ptr) {
99 #ifdef DO_MEMORY_USAGE
100  TypeHandle type = get_type_handle(To);
101  if (type == TypeHandle::none()) {
102  do_init_type(To);
103  type = get_type_handle(To);
104  }
105  if (type != TypeHandle::none()) {
106  MemoryUsage::update_type(ptr, type);
107  }
108 #endif // DO_MEMORY_USAGE
109 }
110 
111 /**
112  * A convenient way to set the ThreadSafePointerTo object to NULL. (Assignment
113  * to a NULL pointer also works, of course.)
114  */
115 template<class T>
117 clear() {
118  reassign(nullptr);
119 }
120 
121 /**
122  * A handy function to output ThreadSafePointerTo's as a hex pointer followed
123  * by a reference count.
124  */
125 template<class T>
127 output(std::ostream &out) const {
128  out << _void_ptr;
129  if (_void_ptr != nullptr) {
130  out << ":" << ((To *)_void_ptr)->get_ref_count();
131  }
132 }
static Pointer get_ptr(const Pointer &var)
Atomically retrieves the snapshot value of the indicated variable.
void output(std::ostream &out) const
A handy function to output ThreadSafePointerTo's as a hex pointer followed by a reference count.
void clear()
A convenient way to set the ThreadSafePointerTo object to NULL.
This is the base class for ThreadSafePointerTo and ThreadSafeConstPointerTo.
static void update_type(ReferenceCount *ptr, TypeHandle type)
Associates the indicated type with the given pointer.
Definition: memoryUsage.I:55
static bool get_track_memory_usage()
Returns true if the user has Configured the variable 'track-memory-usage' to true,...
Definition: memoryUsage.I:20
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.