From 26f40730034378f59ddd62c53220b563c2f7f08f Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 5 Apr 2007 13:36:29 +0000 Subject: [PATCH] resolve threading crash --- dtool/src/dtoolbase/deletedChain.T | 23 ++++++++++++++--------- dtool/src/dtoolbase/deletedChain.h | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/dtool/src/dtoolbase/deletedChain.T b/dtool/src/dtoolbase/deletedChain.T index a71aca370d..b1b63d584f 100644 --- a/dtool/src/dtoolbase/deletedChain.T +++ b/dtool/src/dtoolbase/deletedChain.T @@ -232,14 +232,14 @@ type_to_node(Type *ptr) { #ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE //////////////////////////////////////////////////////////////////// // Function: DeletedChain::init_lock -// Access: Private +// Access: Private, Static // Description: Ensures the lock pointer has been allocated. //////////////////////////////////////////////////////////////////// template INLINE void DeletedChain:: init_lock() { if (_lock == (MutexImpl *)NULL) { - do_init_lock(); + do_init_lock(_lock); } } #endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE @@ -247,26 +247,31 @@ init_lock() { #ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE //////////////////////////////////////////////////////////////////// // Function: DeletedChain::do_init_lock -// Access: Private -// Description: Allocates the lock pointer if necessary. Makes some +// Access: Private, Static +// Description: Allocates the lock pointer if necessary. Takes some // pains to protect itself from race conditions. +// +// We have to receive the MutexImpl object as a +// parameter, because this is a non-inline function, and +// the template pointer might get evaluated differently +// for inline vs. non-inline functions. //////////////////////////////////////////////////////////////////// template void DeletedChain:: -do_init_lock() { - MutexImpl *lock = new MutexImpl; +do_init_lock(MutexImpl *lock) { + MutexImpl *new_lock = new MutexImpl; // Even though DELETED_CHAIN_USE_ATOMIC_EXCHANGE is not true, we // will take advantage of the atomic exchange operation here, at // startup. We have to rely on something, after all, before we have // created the first mutex. MutexImpl *result; - result = (MutexImpl *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_lock, (void *)NULL, (void *)lock); + result = (MutexImpl *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)lock, (void *)NULL, (void *)new_lock); if (result != NULL) { - delete lock; + delete new_lock; } - assert(_lock != (MutexImpl *)NULL); + assert(lock != (MutexImpl *)NULL); } #endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE diff --git a/dtool/src/dtoolbase/deletedChain.h b/dtool/src/dtoolbase/deletedChain.h index 80970b6200..87a801b83c 100644 --- a/dtool/src/dtoolbase/deletedChain.h +++ b/dtool/src/dtoolbase/deletedChain.h @@ -119,7 +119,7 @@ private: // If we don't have atomic compare-and-exchange, we need to use a // Mutex to protect the above linked list. static INLINE void init_lock(); - static void do_init_lock(); + static void do_init_lock(MutexImpl *lock); static MutexImpl *_lock; #endif };