Пример #1
0
void HandleSystem::ReleasePrimHandle(unsigned int index)
{
	QHandle *pHandle = &m_Handles[index];
	HandleSet set = pHandle->set;

	if (pHandle->owner && (set != HandleSet_Identity))
	{
		UnlinkHandleFromOwner(pHandle, index);
	}

	/* Were we an identity ourself? */
	QHandle *pLocal;
	if (set == HandleSet_Identity)
	{
		/* Extra work to do.  We need to find everything connected to this identity and release it. */
		unsigned int ch_index;
#if defined _DEBUG
		unsigned int old_index = 0;
#endif
		while ((ch_index = pHandle->ch_next) != 0)
		{
			pLocal = &m_Handles[ch_index];
#if defined _DEBUG
			assert(old_index != ch_index);
			assert(pLocal->set == HandleSet_Used);
			old_index = ch_index;
#endif
			FreeHandle(pLocal, ch_index);
		}
	}

	pHandle->set = HandleSet_None;
	m_Types[pHandle->type].opened--;
	m_Handles[++m_FreeHandles].freeID = index;
}
Пример #2
0
HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
{
    QHandleType *pType = &m_Types[pHandle->type];

    if (pHandle->clone)
    {
        /* If we're a clone, decrease the parent reference count */
        QHandle *pMaster;
        unsigned int master;

        /* Note that if we ever have per-handle security, we would need to re-check
        * the access on this Handle. */
        master = pHandle->clone;
        pMaster = &m_Handles[master];

        /* Release the clone now */
        ReleasePrimHandle(index);

        /* Decrement the master's reference count */
        if (--pMaster->refcount == 0)
        {
            /* 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);
        }
    } else if (pHandle->set == HandleSet_Identity) {
        /* If we're an identity, skip all this stuff!
         * NOTE: SHARESYS DOES NOT CARE ABOUT THE DESTRUCTOR
         */
        ReleasePrimHandle(index);
    } else {
        /* Decrement, free if necessary */
        if (--pHandle->refcount == 0)
        {
            pHandle->is_destroying = true;
            pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
            ReleasePrimHandle(index);
        } else {
            /* We must be cloned, so mark ourselves as freed */
            pHandle->set = HandleSet_Freed;
            /* Now, unlink us, so we're not being tracked by the owner */
            if (pHandle->owner)
            {
                UnlinkHandleFromOwner(pHandle, index);
            }
        }
    }

    return HandleError_None;
}