Added a re-entrancy check to Handles so the destructor won't fire twice in certain cases
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40795
This commit is contained in:
parent
b0a32b39c2
commit
d1dea716a6
@ -285,6 +285,7 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
pHandle->owner = owner;
|
||||
pHandle->ch_next = 0;
|
||||
pHandle->access_special = false;
|
||||
pHandle->is_destroying = false;
|
||||
|
||||
/* Create the hash value */
|
||||
Handle_t hash = pHandle->serial;
|
||||
@ -601,6 +602,7 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
||||
{
|
||||
/* Type should be the same but do this anyway... */
|
||||
pType = &m_Types[pMaster->type];
|
||||
pMaster->is_destroying = true;
|
||||
pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
|
||||
ReleasePrimHandle(master);
|
||||
}
|
||||
@ -613,6 +615,7 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
||||
/* Decrement, free if necessary */
|
||||
if (--pHandle->refcount == 0)
|
||||
{
|
||||
pHandle->is_destroying = true;
|
||||
pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
|
||||
ReleasePrimHandle(index);
|
||||
} else {
|
||||
@ -646,6 +649,14 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, const HandleSecurity *pSec
|
||||
return HandleError_Access;
|
||||
}
|
||||
|
||||
if (pHandle->is_destroying)
|
||||
{
|
||||
/* Someone tried to free this recursively.
|
||||
* We'll just ignore this safely.
|
||||
*/
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
return FreeHandle(pHandle, index);
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ struct QHandle
|
||||
unsigned int clone; /* If non-zero, this is our cloned parent index */
|
||||
HandleSet set; /* Information about the handle's state */
|
||||
bool access_special; /* Whether or not access rules are special or type-derived */
|
||||
bool is_destroying; /* Whether or not the handle is being destroyed */
|
||||
HandleAccess sec; /* Security rules */
|
||||
/* The following variables are unrelated to the Handle array, and used
|
||||
* as an inlined chain of information */
|
||||
|
Loading…
Reference in New Issue
Block a user