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;