resolve threading crash

This commit is contained in:
David Rose 2007-04-05 13:36:29 +00:00
parent 375450db4b
commit 26f4073003
2 changed files with 15 additions and 10 deletions

View File

@ -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<class Type>
INLINE void DeletedChain<Type>::
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<class Type>
void DeletedChain<Type>::
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

View File

@ -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
};