27 if (_cow_object ==
nullptr) {
31 MutexHolder holder(_cow_object->_lock_mutex);
32 while (_cow_object->_lock_status == CopyOnWriteObject::LS_locked_write) {
33 if (_cow_object->_locking_thread == current_thread) {
36 if (util_cat.is_debug()) {
38 << *current_thread <<
" waiting on " << _cow_object->get_type()
39 <<
" " << _cow_object <<
", held by " << *_cow_object->_locking_thread
42 _cow_object->_lock_cvar.wait();
45 _cow_object->_lock_status = CopyOnWriteObject::LS_locked_read;
46 _cow_object->_locking_thread = current_thread;
63 if (_cow_object ==
nullptr) {
69 _cow_object->_lock_mutex.lock();
70 while (_cow_object->_lock_status == CopyOnWriteObject::LS_locked_write &&
71 _cow_object->_locking_thread != current_thread) {
72 if (util_cat.is_debug()) {
74 << *current_thread <<
" waiting on " << _cow_object->get_type()
75 <<
" " << _cow_object <<
", held by " << *_cow_object->_locking_thread
78 _cow_object->_lock_cvar.wait();
81 if (_cow_object->_lock_status == CopyOnWriteObject::LS_locked_read) {
82 nassertr(_cow_object->get_ref_count() > _cow_object->get_cache_ref_count(),
nullptr);
84 if (util_cat.is_debug()) {
86 <<
"Making copy of " << _cow_object->get_type()
87 <<
" because it is locked in read mode.\n";
90 PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy();
91 _cow_object->CachedTypedWritableReferenceCount::cache_unref();
92 _cow_object->_lock_mutex.unlock();
94 MutexHolder holder(new_object->_lock_mutex);
95 _cow_object = new_object;
96 _cow_object->CachedTypedWritableReferenceCount::cache_ref();
97 _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
98 _cow_object->_locking_thread = current_thread;
102 }
else if (_cow_object->get_cache_ref_count() > 1) {
106 if (util_cat.is_debug()) {
108 <<
"Making copy of " << _cow_object->get_type()
109 <<
" because it is shared by " << _cow_object->get_ref_count()
113 PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy();
114 _cow_object->CachedTypedWritableReferenceCount::cache_unref();
115 _cow_object->_lock_mutex.unlock();
117 MutexHolder holder(new_object->_lock_mutex);
118 _cow_object = new_object;
119 _cow_object->CachedTypedWritableReferenceCount::cache_ref();
120 _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
121 _cow_object->_locking_thread = current_thread;
133 _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
134 _cow_object->_locking_thread = current_thread;
135 _cow_object->_lock_mutex.unlock();
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
const CopyOnWriteObject * get_read_pointer(Thread *current_thread) const
Returns a pointer locked for read.
CopyOnWriteObject * get_write_pointer()
Returns a pointer locked for write.
A thread; that is, a lightweight process.
get_current_thread
Returns a pointer to the currently-executing Thread object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.