| 677 | } |
| 678 | |
| 679 | HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index) |
| 680 | { |
| 681 | if (pHandle->is_destroying) |
| 682 | { |
| 683 | /* Someone tried to free this recursively. |
| 684 | * We'll just ignore this safely. |
| 685 | */ |
| 686 | return HandleError_None; |
| 687 | } |
| 688 | |
| 689 | QHandleType *pType = &m_Types[pHandle->type]; |
| 690 | |
| 691 | if (pHandle->owner && pHandle->owner->num_handles > 0) |
| 692 | pHandle->owner->num_handles--; |
| 693 | |
| 694 | if (pHandle->clone) |
| 695 | { |
| 696 | /* If we're a clone, decrease the parent reference count */ |
| 697 | QHandle *pMaster; |
| 698 | unsigned int master; |
| 699 | |
| 700 | /* Note that if we ever have per-handle security, we would need to re-check |
| 701 | * the access on this Handle. */ |
| 702 | master = pHandle->clone; |
| 703 | pMaster = &m_Handles[master]; |
| 704 | |
| 705 | /* Release the clone now */ |
| 706 | pHandle->is_destroying = true; |
| 707 | ReleasePrimHandle(index); |
| 708 | |
| 709 | /* Decrement the master's reference count */ |
| 710 | if (--pMaster->refcount == 0) |
| 711 | { |
| 712 | /* Type should be the same but do this anyway... */ |
| 713 | pType = &m_Types[pMaster->type]; |
| 714 | pMaster->is_destroying = true; |
| 715 | if (pMaster->object) |
| 716 | { |
| 717 | pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object); |
| 718 | } |
| 719 | ReleasePrimHandle(master); |
| 720 | } |
| 721 | } else if (pHandle->set == HandleSet_Identity) { |
| 722 | /* If we're an identity, skip all this stuff! |
| 723 | * NOTE: SHARESYS DOES NOT CARE ABOUT THE DESTRUCTOR |
| 724 | */ |
| 725 | pHandle->is_destroying = true; |
| 726 | ReleasePrimHandle(index); |
| 727 | } else { |
| 728 | /* Decrement, free if necessary */ |
| 729 | if (--pHandle->refcount == 0) |
| 730 | { |
| 731 | pHandle->is_destroying = true; |
| 732 | if (pHandle->object) |
| 733 | { |
| 734 | pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object); |
| 735 | } |
| 736 | ReleasePrimHandle(index); |
no test coverage detected