Logo Search packages:      
Sourcecode: virtualbox-ose version File versions  Download package

void kldrDyldModDestroy ( PKLDRDYLDMOD  pMod  ) 

Destroys a module pending destruction.

Parameters:
pMod The module in question.

Definition at line 233 of file kLdrDyldMod.c.

References KLDRDYLDMOD::cDepRefs, KLDRDYLDMOD::cDynRefs, KLDRDYLDMOD::cPrereqs, KLDRDYLDMOD::cRefs, KLDRDYLDMOD::enmState, KLDRDYLDMOD::fAllocatedTLS, KLDRDYLDMOD::fInitList, KLDRDYLDMOD::fMapped, KLDRDYLDMOD_ASSERT, kldrDyldModUnlink(), kLdrModClose(), kLdrModFreeTLS(), kLdrModUnmap(), KLDRSTATE_DESTROYED, KLDRSTATE_GC, KLDRSTATE_PENDING_DESTROY, NULL, KLDRDYLDMOD::papPrereqs, KLDRDYLDMOD::pMod, KLDRDYLDMOD::u32MagicHead, and KLDRDYLDMOD::u32MagicTail.

Referenced by kldrDyldDoModuleTerminationAndGarabageCollection().

{
    int rc;

    /*
     * Validate the state.
     */
    switch (pMod->enmState)
    {
        case KLDRSTATE_PENDING_DESTROY:
        case KLDRSTATE_GC:
            break;
        default:
            KLDRDYLDMOD_ASSERT(!"Invalid state");
            break;
    }
    KLDRDYLDMOD_ASSERT(!pMod->fInitList);
    KLDRDYLDMOD_ASSERT(!pMod->cDynRefs);
    KLDRDYLDMOD_ASSERT(!pMod->cDepRefs);

    /*
     * Ensure that the module is unmapped.
     */
    if (pMod->fAllocatedTLS)
    {
        kLdrModFreeTLS(pMod->pMod);
        pMod->fAllocatedTLS = 0;
    }
    if (pMod->fMapped)
    {
        rc = kLdrModUnmap(pMod->pMod); KLDRDYLDMOD_ASSERT(!rc);
        pMod->fMapped = 0;
    }

    /*
     * Ensure it's unlinked from all chains.
     */
    if (pMod->enmState < KLDRSTATE_PENDING_DESTROY)
        kldrDyldModUnlink(pMod);

    /*
     * Free everything associated with the module.
     */
    /* the prerequisite array. */
    if (pMod->papPrereqs)
    {
        KU32 i = pMod->cPrereqs;
        while (i-- > 0)
        {
            KLDRDYLDMOD_ASSERT(pMod->papPrereqs[i] == NULL);
            pMod->papPrereqs[i] = NULL;
        }

        kHlpFree(pMod->papPrereqs);
        pMod->papPrereqs = NULL;
        pMod->cPrereqs = 0;
    }

    /* the module interpreter.  */
    if (pMod->pMod)
    {
        rc = kLdrModClose(pMod->pMod); KLDRDYLDMOD_ASSERT(!rc);
        pMod->pMod = NULL;
    }


    /*
     * Finally, change the module state and free the module if
     * there are not more references to it. If somebody is still
     * referencing it, postpone the freeing to Deref.
     */
    pMod->enmState = KLDRSTATE_DESTROYED;
    if (!pMod->cRefs)
    {
        pMod->u32MagicHead = 1;
        pMod->u32MagicTail = 2;
        kHlpFree(pMod);
    }
}


Generated by  Doxygen 1.6.0   Back to index