예제 #1
0
/**
 * Suspend all running threads.
 *
 * This is called by PDMR3Suspend() and PDMR3PowerOff() after all the devices
 * and drivers have been notified about the suspend / power off.
 *
 * @return VBox status code.
 * @param   pVM         Pointer to the VM.
 */
int pdmR3ThreadSuspendAll(PVM pVM)
{
    PUVM pUVM = pVM->pUVM;
    RTCritSectEnter(&pUVM->pdm.s.ListCritSect); /* This may cause deadlocks later... */
    for (PPDMTHREAD pThread = pUVM->pdm.s.pThreads; pThread; pThread = pThread->Internal.s.pNext)
        switch (pThread->enmState)
        {
            case PDMTHREADSTATE_RUNNING:
            {
                int rc = PDMR3ThreadSuspend(pThread);
                AssertRCReturn(rc, rc);
                break;
            }

            /* suspend -> power off; voluntary suspend. */
            case PDMTHREADSTATE_SUSPENDED:
                break;

            default:
                AssertMsgFailed(("pThread=%p enmState=%d\n", pThread, pThread->enmState));
                break;
        }
    RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
    return VINF_SUCCESS;
}
/**
 * Callback employed by drvscsiSuspend and drvscsiPowerOff.
 *
 * @returns true if we've quiesced, false if we're still working.
 * @param   pDrvIns     The driver instance.
 */
static DECLCALLBACK(bool) drvscsiIsAsyncSuspendOrPowerOffDone(PPDMDRVINS pDrvIns)
{
    PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);

    if (pThis->pDrvBlockAsync)
    {
        if (pThis->StatIoDepth > 0)
            return false;
        else
            return true;
    }
    else
    {
        if (!drvscsiAsyncIOLoopNoPendingDummy(pThis, 0 /*ms*/))
            return false;
        ASMAtomicWriteBool(&pThis->fDummySignal, false);
        PDMR3ThreadSuspend(pThis->pAsyncIOThread);
        return true;
    }
}