mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
attempt to robustify
This commit is contained in:
parent
b39ca2fec5
commit
3010785e58
@ -169,6 +169,32 @@ deallocate(Type *ptr, TypeHandle type_handle) {
|
||||
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::validate
|
||||
// Access: Public
|
||||
// Description: Returns true if the pointer is valid, false if it has
|
||||
// been deleted or if it was never a valid pointer.
|
||||
//
|
||||
// This is only meaningful in debug mode, where
|
||||
// USE_DELETEDCHAINFLAG is defined. If not, this
|
||||
// trivially returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Type>
|
||||
INLINE bool DeletedChain<Type>::
|
||||
validate(const Type *ptr) {
|
||||
TAU_PROFILE("bool DeletedChain<Type>::validate(Type *)", " ", TAU_USER);
|
||||
if (ptr == (Type *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_DELETEDCHAINFLAG
|
||||
TVOLATILE const ObjectNode *obj = type_to_node((Type *)ptr);
|
||||
return AtomicAdjust::get(obj->_flag) == DCF_alive;
|
||||
#else
|
||||
return true;
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::node_to_type
|
||||
// Access: Private, Static
|
||||
@ -213,7 +239,34 @@ template<class Type>
|
||||
INLINE void DeletedChain<Type>::
|
||||
init_lock() {
|
||||
if (_lock == (MutexImpl *)NULL) {
|
||||
_lock = new MutexImpl;
|
||||
do_init_lock();
|
||||
}
|
||||
}
|
||||
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
|
||||
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::do_init_lock
|
||||
// Access: Private
|
||||
// Description: Allocates the lock pointer if necessary. Makes some
|
||||
// pains to protect itself from race conditions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Type>
|
||||
void DeletedChain<Type>::
|
||||
do_init_lock() {
|
||||
MutexImpl *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);
|
||||
|
||||
if (result != NULL) {
|
||||
delete lock;
|
||||
}
|
||||
|
||||
assert(_lock != (MutexImpl *)NULL);
|
||||
}
|
||||
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
|
@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
// In development mode, we defined USE_DELETEDCHAINFLAG, which
|
||||
// In development mode, we define USE_DELETEDCHAINFLAG, which
|
||||
// triggers the piggyback of an additional word of data on every
|
||||
// allocated block, so we can ensure that an object is not
|
||||
// double-deleted and that the deleted chain remains intact.
|
||||
@ -85,6 +85,8 @@ public:
|
||||
INLINE static Type *allocate(size_t size, TypeHandle type_handle);
|
||||
INLINE static void deallocate(Type *ptr, TypeHandle type_handle);
|
||||
|
||||
INLINE static bool validate(const Type *ptr);
|
||||
|
||||
private:
|
||||
class ObjectNode {
|
||||
public:
|
||||
@ -117,6 +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 MutexImpl *_lock;
|
||||
#endif
|
||||
};
|
||||
@ -126,15 +129,18 @@ private:
|
||||
// DeletedChain.
|
||||
#define ALLOC_DELETED_CHAIN(Type) \
|
||||
inline void *operator new(size_t size) { \
|
||||
return (void *)DeletedChain< Type >::allocate(size, get_type_handle(Type)); \
|
||||
return (void *)DeletedChain< Type >::allocate(size, get_type_handle(Type)); \
|
||||
} \
|
||||
inline void *operator new(size_t size, void *ptr) { \
|
||||
return ptr; \
|
||||
} \
|
||||
inline void operator delete(void *ptr) { \
|
||||
DeletedChain< Type >::deallocate((Type *)ptr, get_type_handle(Type)); \
|
||||
DeletedChain< Type >::deallocate((Type *)ptr, get_type_handle(Type)); \
|
||||
} \
|
||||
inline void operator delete(void *, void *) { \
|
||||
} \
|
||||
inline static bool validate_ptr(const void *ptr) { \
|
||||
return DeletedChain< Type >::validate((const Type *)ptr); \
|
||||
}
|
||||
|
||||
#include "deletedChain.T"
|
||||
|
Loading…
x
Reference in New Issue
Block a user