VirtualBox

Changeset 90026 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jul 5, 2021 1:54:56 PM (3 years ago)
Author:
vboxsync
Message:

VUSB/Win: Improved logging, reworked Windows backend so that usbProxyWinUrbReap() doesn't return NULL for no good reason.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/win/USBProxyDevice-win.cpp

    r82968 r90026  
    5757    uint8_t         bInterfaceNumber;
    5858    bool            fClaimed;
     59    /** Set if reaper should exit ASAP. */
     60    bool            fWakeUpNow;
    5961    /** The allocated size of paHandles and paQueuedUrbs. */
    6062    unsigned        cAllocatedUrbs;
     
    9799        || dwErr == ERROR_BAD_COMMAND)
    98100    {
    99         Log(("usbproxy: device %x unplugged!!\n", pPriv->hDev));
     101        Log(("usbproxy: device %x unplugged!! (usbProxyWinHandleUnpluggedDevice)\n", pPriv->hDev));
    100102        pProxyDev->fDetached = true;
    101103    }
     
    277279    if (rc == ERROR_DEVICE_REMOVED)
    278280    {
    279         Log(("usbproxy: device %p unplugged!!\n", pPriv->hDev));
     281        Log(("usbproxy: device %p unplugged!! (usbProxyWinReset)\n", pPriv->hDev));
    280282        pProxyDev->fDetached = true;
    281283    }
     
    495497                || dwErr == ERROR_BAD_COMMAND)
    496498            {
    497                 Log(("usbproxy: device %p unplugged!!\n", pPriv->hDev));
     499                Log(("usbproxy: device %p unplugged!! (usbProxyWinUrbQueue)\n", pPriv->hDev));
    498500                pProxyDev->fDetached = true;
    499501            }
     
    566568        && pPriv->cPendingUrbs == 0)
    567569    {
     570        Log(("usbproxy: Nothing pending\n"));
    568571        if (   cMillies != 0
    569572            && pPriv->cPendingUrbs == 0)
    570573        {
    571574            /* Wait for the wakeup call. */
     575            Log(("usbproxy: Waiting for wakeup call\n"));
    572576            DWORD cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies;
    573             DWORD dwRc = WaitForMultipleObjects(1, &pPriv->hEventWakeup, FALSE, cMilliesWait);
    574             NOREF(dwRc);
    575         }
    576 
     577            DWORD rc = WaitForMultipleObjects(1, &pPriv->hEventWakeup, FALSE, cMilliesWait);
     578            Log(("usbproxy: Initial wait rc=%X\n", rc));
     579            if (rc != WAIT_OBJECT_0) {
     580                Log(("usbproxy: Initial wait failed, rc=%X\n", rc));
     581                return NULL;
     582            }
     583        }
    577584        return NULL;
    578585    }
     
    580587again:
    581588    /* Check for pending URBs. */
     589    Log(("usbproxy: %u pending URBs\n", pPriv->cPendingUrbs));
    582590    if (pPriv->cPendingUrbs)
    583591    {
     
    623631     * Wait/poll.
    624632     *
    625      * ASSUMPTIONS:
    626      *   1. The usbProxyWinUrbReap can not be run concurrently with each other
    627      *      so racing the cQueuedUrbs access/modification can not occur.
    628      *   2. The usbProxyWinUrbReap can not be run concurrently with
    629      *      usbProxyWinUrbQueue so they can not race the pPriv->paHandles
    630      *      access/realloc.
     633     * ASSUMPTION: Multiple usbProxyWinUrbReap calls can not be run concurrently
     634     *   with each other so racing the cQueuedUrbs access/modification can not occur.
     635     *
     636     * However, usbProxyWinUrbReap can be run concurrently with usbProxyWinUrbQueue
     637     * and pPriv->paHandles access/realloc must be synchronized.
     638     *
     639     * NB: Due to the design of Windows overlapped I/O, DeviceIoControl calls to submit
     640     * URBs use individual event objects. When a new URB is submitted, we have to add its
     641     * event object to the list of objects that WaitForMultipleObjects is waiting on. Thus
     642     * hEventWakeup has dual purpose, serving to handle proxy wakeup calls meant to abort
     643     * reaper waits, but also waking up the reaper after every URB submit so that the newly
     644     * submitted URB can be added to the list of waiters.
    631645     */
    632646    unsigned cQueuedUrbs = ASMAtomicReadU32((volatile uint32_t *)&pPriv->cQueuedUrbs);
     
    634648    PVUSBURB pUrb = NULL;
    635649    DWORD rc = WaitForMultipleObjects(cQueuedUrbs + 1, pPriv->paHandles, FALSE, cMilliesWait);
     650    Log(("usbproxy: Wait (%d milliseconds) returned with rc=%X\n", cMilliesWait, rc));
    636651
    637652    /* If the wakeup event fired return immediately. */
    638653    if (rc == WAIT_OBJECT_0 + cQueuedUrbs)
    639654    {
    640         if (pPriv->cPendingUrbs)
    641             goto again;
    642         return NULL;
     655        /* Get outta here flag set? If so, bail now. */
     656        if (ASMAtomicXchgBool(&pPriv->fWakeUpNow, false))
     657        {
     658            Log(("usbproxy: Reaper woken up, returning NULL\n"));
     659            return NULL;
     660        }
     661
     662        /* A new URBs was queued through usbProxyWinUrbQueue() and needs to be
     663         * added to the wait list. Go again.
     664         */
     665        Log(("usbproxy: Reaper woken up after queuing new URB, go again.\n"));
     666        goto again;
    643667    }
    644668
     
    724748    AssertPtrReturn(pQUrbWin, VERR_INVALID_PARAMETER);
    725749
    726     in.bEndpoint = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0);
     750    in.bEndpoint = pUrb->EndPt | ((pUrb->EndPt && pUrb->enmDir == VUSBDIRECTION_IN) ? 0x80 : 0);
    727751    Log(("usbproxy: Cancel urb %p, endpoint %x\n", pUrb, in.bEndpoint));
    728752
     
    735759        || dwErr == ERROR_BAD_COMMAND)
    736760    {
    737         Log(("usbproxy: device %x unplugged!!\n", pPriv->hDev));
     761        Log(("usbproxy: device %x unplugged!! (usbProxyWinUrbCancel)\n", pPriv->hDev));
    738762        pProxyDev->fDetached = true;
    739763        return VINF_SUCCESS; /* Fake success and deal with the unplugged device elsewhere. */
     
    748772    PPRIV_USBW32 pPriv = USBPROXYDEV_2_DATA(pProxyDev, PPRIV_USBW32);
    749773
     774    Log(("usbproxy: device %x wakeup\n", pPriv->hDev));
     775    ASMAtomicXchgBool(&pPriv->fWakeUpNow, true);
    750776    SetEvent(pPriv->hEventWakeup);
    751777    return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette