core/HandleSys.cpp
changeset 3838 aa2d7aa5322f
parent 3837 f86a51ee4eb4
     1.1 --- a/core/HandleSys.cpp	Sun Mar 17 21:58:56 2013 +0000
     1.2 +++ b/core/HandleSys.cpp	Sun Mar 17 22:05:33 2013 +0000
     1.3 @@ -579,6 +579,7 @@
     1.4  	}
     1.5  
     1.6  	pNewHandle->clone = index;
     1.7 +	pNewHandle->object = NULL;
     1.8  	pHandle->refcount++;
     1.9  
    1.10  	*newhandle = new_handle;
    1.11 @@ -659,6 +660,14 @@
    1.12  
    1.13  HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
    1.14  {
    1.15 +	if (pHandle->is_destroying)
    1.16 +	{
    1.17 +		/* Someone tried to free this recursively.  
    1.18 +		 * We'll just ignore this safely.
    1.19 +		 */
    1.20 +		return HandleError_None;
    1.21 +	}
    1.22 +
    1.23  	QHandleType *pType = &m_Types[pHandle->type];
    1.24  
    1.25  	if (pHandle->clone)
    1.26 @@ -673,6 +682,7 @@
    1.27  		pMaster = &m_Handles[master];
    1.28  
    1.29  		/* Release the clone now */
    1.30 +		pHandle->is_destroying = true;
    1.31  		ReleasePrimHandle(index);
    1.32  
    1.33  		/* Decrement the master's reference count */
    1.34 @@ -681,20 +691,27 @@
    1.35  			/* Type should be the same but do this anyway... */
    1.36  			pType = &m_Types[pMaster->type];
    1.37  			pMaster->is_destroying = true;
    1.38 -			pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
    1.39 +			if (pMaster->object)
    1.40 +			{
    1.41 +				pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
    1.42 +			}
    1.43  			ReleasePrimHandle(master);
    1.44  		}
    1.45  	} else if (pHandle->set == HandleSet_Identity) {
    1.46  		/* If we're an identity, skip all this stuff!
    1.47  		 * NOTE: SHARESYS DOES NOT CARE ABOUT THE DESTRUCTOR
    1.48  		 */
    1.49 +		pHandle->is_destroying = true;
    1.50  		ReleasePrimHandle(index);
    1.51  	} else {
    1.52  		/* Decrement, free if necessary */
    1.53  		if (--pHandle->refcount == 0)
    1.54  		{
    1.55  			pHandle->is_destroying = true;
    1.56 -			pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
    1.57 +			if (pHandle->object)
    1.58 +			{
    1.59 +				pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
    1.60 +			}
    1.61  			ReleasePrimHandle(index);
    1.62  		} else {
    1.63  			/* We must be cloned, so mark ourselves as freed */
    1.64 @@ -727,14 +744,6 @@
    1.65  		return HandleError_Access;
    1.66  	}
    1.67  
    1.68 -	if (pHandle->is_destroying)
    1.69 -	{
    1.70 -		/* Someone tried to free this recursively.  
    1.71 -		 * We'll just ignore this safely.
    1.72 -		 */
    1.73 -		return HandleError_None;
    1.74 -	}
    1.75 -
    1.76  	return FreeHandle(pHandle, index);
    1.77  }
    1.78  
    1.79 @@ -793,6 +802,9 @@
    1.80  		assert(pHandle->owner == 0);
    1.81  		return;
    1.82  	}
    1.83 +
    1.84 +	pHandle->owner = NULL;
    1.85 +
    1.86  	/* Note that since 0 is an invalid handle, if any of these links are 0,
    1.87  	* the data can still be set.
    1.88  	*/
    1.89 @@ -917,29 +929,9 @@
    1.90  			{
    1.91  				continue;
    1.92  			}
    1.93 -			if (pHandle->clone)
    1.94 -			{
    1.95 -				/* Get parent */
    1.96 -				QHandle *pOther = &m_Handles[pHandle->clone];
    1.97 -				if (--pOther->refcount == 0)
    1.98 -				{
    1.99 -					/* Free! */
   1.100 -					dispatch->OnHandleDestroy(type, pOther->object);
   1.101 -					ReleasePrimHandle(pHandle->clone);
   1.102 -				}
   1.103 -				/* Unlink ourselves since we don't have a reference count */
   1.104 -				ReleasePrimHandle(i);
   1.105 -			} else {
   1.106 -				/* If it's not a clone, we still have to check the reference count.
   1.107 -				 * Either way, we'll be destroyed eventually because the handle types do not change.
   1.108 -				 */
   1.109 -				if (--pHandle->refcount == 0)
   1.110 -				{
   1.111 -					/* Free! */
   1.112 -					dispatch->OnHandleDestroy(type, pHandle->object);
   1.113 -					ReleasePrimHandle(i);
   1.114 -				}
   1.115 -			}
   1.116 +
   1.117 +			FreeHandle(pHandle, i);
   1.118 +
   1.119  			if (pType->opened == 0)
   1.120  			{
   1.121  				break;