From 63be56cd0e6516d8fead2a3053c1ce12fa383413 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 10 Mar 2017 15:46:03 +0100 Subject: [PATCH] Backport part of b21e8fdf3216b9a18d7f2edef9fc5ce5590f9969 that fixes an issue with geometry generation when multithreaded pipeline is enabled Fixes bullet soft body issue as well as LP 1671639 --- panda/src/putil/copyOnWritePointer.cxx | 28 +++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/panda/src/putil/copyOnWritePointer.cxx b/panda/src/putil/copyOnWritePointer.cxx index c323cb76c0..ad487e1701 100644 --- a/panda/src/putil/copyOnWritePointer.cxx +++ b/panda/src/putil/copyOnWritePointer.cxx @@ -99,19 +99,17 @@ get_write_pointer() { } PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy(); + _cow_object->CachedTypedWritableReferenceCount::cache_unref(); + _cow_object->_lock_mutex.release(); - // We can't call cache_unref_delete, because we hold the lock. - if (!_cow_object->CachedTypedWritableReferenceCount::cache_unref()) { - _cow_object->_lock_mutex.release(); - delete _cow_object; - } else { - _cow_object->_lock_mutex.release(); - } + MutexHolder holder(new_object->_lock_mutex); _cow_object = new_object; - _cow_object->cache_ref(); + _cow_object->CachedTypedWritableReferenceCount::cache_ref(); _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write; _cow_object->_locking_thread = current_thread; + return new_object; + } else if (_cow_object->get_cache_ref_count() > 1) { // No one else has it specifically read-locked, but there are // other CopyOnWritePointers holding the same object, so we should @@ -124,19 +122,17 @@ get_write_pointer() { } PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy(); + _cow_object->CachedTypedWritableReferenceCount::cache_unref(); + _cow_object->_lock_mutex.release(); - // We can't call cache_unref_delete, because we hold the lock. - if (!_cow_object->CachedTypedWritableReferenceCount::cache_unref()) { - _cow_object->_lock_mutex.release(); - delete _cow_object; - } else { - _cow_object->_lock_mutex.release(); - } + MutexHolder holder(new_object->_lock_mutex); _cow_object = new_object; - _cow_object->cache_ref(); + _cow_object->CachedTypedWritableReferenceCount::cache_ref(); _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write; _cow_object->_locking_thread = current_thread; + return new_object; + } else { // No other thread has the pointer locked, and we're the only // CopyOnWritePointer with this object. We can safely write to it