Exemplo n.º 1
0
/**
 * @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease
 */
static DECLCALLBACK(void) vboxNetAdpPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort)
{
    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);
    RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;

    /*
     * Serious paranoia.
     */
    AssertPtr(pThis);
    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
    Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
    AssertPtr(pThis->pGlobals);
    Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
    Assert(pThis->hSpinlock != NIL_RTSPINLOCK);


    /*
     * Disconnect and release it.
     */
    RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
    //Assert(vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Connected);
    Assert(!pThis->cBusy);
    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Transitional);
    RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);

    vboxNetAdpOsDisconnectIt(pThis);
    pThis->pSwitchPort = NULL;

    RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Available);
    RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);

    vboxNetAdpRelease(pThis);
}
Exemplo n.º 2
0
/**
 * @copydoc INTNETTRUNKIFPORT::pfnSetActive
 */
static DECLCALLBACK(bool) vboxNetAdpPortSetActive(PINTNETTRUNKIFPORT pIfPort, bool fActive)
{
    bool fPreviouslyActive;
    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);

    /*
     * Input validation.
     */
    AssertPtr(pThis);
    AssertPtr(pThis->pGlobals);
    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);

    Log(("vboxNetAdpPortSetActive: pThis=%p, fActive=%d, state before: %d.\n", pThis, fActive, vboxNetAdpGetState(pThis)));
    RTSpinlockAcquire(pThis->hSpinlock);

    fPreviouslyActive = vboxNetAdpGetState(pThis) == kVBoxNetAdpState_Active;
    if (fPreviouslyActive != fActive)
    {
        switch (vboxNetAdpGetState(pThis))
        {
            case kVBoxNetAdpState_Connected:
                vboxNetAdpSetState(pThis, kVBoxNetAdpState_Active);
                break;
            case kVBoxNetAdpState_Active:
                vboxNetAdpSetState(pThis, kVBoxNetAdpState_Connected);
                break;
            default:
                break;
        }
    }

    RTSpinlockRelease(pThis->hSpinlock);
    Log(("vboxNetAdpPortSetActive: state after: %RTbool.\n", vboxNetAdpGetState(pThis)));
    return fPreviouslyActive;
}
Exemplo n.º 3
0
int vboxNetAdpCreate(PINTNETTRUNKFACTORY pIfFactory, PVBOXNETADP *ppNew)
{
    int rc;
    unsigned i;
    PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, TrunkFactory));

    for (i = 0; i < RT_ELEMENTS(pGlobals->aAdapters); i++)
    {
        RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
        PVBOXNETADP pThis = &pGlobals->aAdapters[i];

        if (vboxNetAdpCheckAndSetState(pThis, kVBoxNetAdpState_Invalid, kVBoxNetAdpState_Transitional))
        {
            /* Found an empty slot -- use it. */
            uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
            Assert(cRefs == 1);
            RTMAC Mac;
            vboxNetAdpComposeMACAddress(pThis, &Mac);
            rc = vboxNetAdpOsCreate(pThis, &Mac);
            *ppNew = pThis;
            RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
            vboxNetAdpSetState(pThis, kVBoxNetAdpState_Available);
            RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
            return rc;
        }
    }

    /* All slots in adapter array are busy. */
    return VERR_OUT_OF_RESOURCES;
}
Exemplo n.º 4
0
/**
 * Sets the enmState member atomically after first acquiring the spinlock.
 *
 * Used for all updates.
 *
 * @param   pThis           The instance.
 * @param   enmNewState     The new value.
 */
DECLINLINE(void) vboxNetAdpSetStateWithLock(PVBOXNETADP pThis, VBOXNETADPSTATE enmNewState)
{
    Log(("vboxNetAdpSetStateWithLock: pThis=%p, state=%d.\n", pThis, enmNewState));
    RTSpinlockAcquire(pThis->hSpinlock);
    vboxNetAdpSetState(pThis, enmNewState);
    RTSpinlockRelease(pThis->hSpinlock);
}
Exemplo n.º 5
0
/**
 * Sets the enmState member atomically after first acquiring the spinlock.
 *
 * Used for all updates.
 *
 * @param   pThis           The instance.
 * @param   enmNewState     The new value.
 */
DECLINLINE(void) vboxNetAdpSetStateWithLock(PVBOXNETADP pThis, VBOXNETADPSTATE enmNewState)
{
    RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
    Log(("vboxNetAdpSetStateWithLock: pThis=%p, state=%d.\n", pThis, enmNewState));
    RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
    vboxNetAdpSetState(pThis, enmNewState);
    RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
}
Exemplo n.º 6
0
int vboxNetAdpDestroy(PVBOXNETADP pThis)
{
    int rc = VINF_SUCCESS;

    RTSpinlockAcquire(pThis->hSpinlock);
    if (vboxNetAdpGetState(pThis) != kVBoxNetAdpState_Available || pThis->cBusy)
    {
        RTSpinlockRelease(pThis->hSpinlock);
        return VERR_INTNET_FLT_IF_BUSY;
    }
    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Transitional);
    RTSpinlockRelease(pThis->hSpinlock);
    vboxNetAdpRelease(pThis);

    vboxNetAdpOsDestroy(pThis);

    RTSpinlockAcquire(pThis->hSpinlock);
    vboxNetAdpSetState(pThis, kVBoxNetAdpState_Invalid);
    RTSpinlockRelease(pThis->hSpinlock);

    return rc;
}
Exemplo n.º 7
0
/**
 * Checks and sets the enmState member atomically.
 *
 * Used for all updates.
 *
 * @returns true if the state has been changed.
 * @param   pThis           The instance.
 * @param   enmNewState     The new value.
 */
DECLINLINE(bool) vboxNetAdpCheckAndSetState(PVBOXNETADP pThis, VBOXNETADPSTATE enmOldState, VBOXNETADPSTATE enmNewState)
{
    VBOXNETADPSTATE enmActualState;
    bool fRc = true; /* be optimistic */

    RTSpinlockAcquire(pThis->hSpinlock);
    enmActualState = vboxNetAdpGetState(pThis); /** @todo r=bird: ASMAtomicCmpXchgU32()*/
    if (enmActualState == enmOldState)
        vboxNetAdpSetState(pThis, enmNewState);
    else
        fRc = false;
    RTSpinlockRelease(pThis->hSpinlock);

    if (fRc)
        Log(("vboxNetAdpCheckAndSetState: pThis=%p, state changed: %d -> %d.\n", pThis, enmOldState, enmNewState));
    else
        Log(("vboxNetAdpCheckAndSetState: pThis=%p, no state change: %d != %d (expected).\n", pThis, enmActualState, enmOldState));
    return fRc;
}