VirtualBox

Changeset 37158 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 19, 2011 3:19:07 PM (14 years ago)
Author:
vboxsync
Message:

dev/usb/win: fix paHandles & paQueuedUrbs realloc racing

File:
1 edited

Legend:

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

    r37144 r37158  
    463463
    464464    /*
    465      * Ensure we've got sufficient space in the arrays.
    466      */
    467     if (pPriv->cQueuedUrbs + 1 > pPriv->cAllocatedUrbs)
    468     {
    469         unsigned cNewMax = pPriv->cAllocatedUrbs + 32;
    470         void *pv = RTMemRealloc(pPriv->paHandles, sizeof(pPriv->paHandles[0]) * cNewMax);
    471         if (!pv)
    472             return false;
    473         pPriv->paHandles = (PHANDLE)pv;
    474         pv = RTMemRealloc(pPriv->paQueuedUrbs, sizeof(pPriv->paQueuedUrbs[0]) * cNewMax);
    475         if (!pv)
    476             return false;
    477         pPriv->paQueuedUrbs = (PQUEUED_URB *)pv;
    478         pPriv->cAllocatedUrbs = cNewMax;
    479     }
    480 
    481     /*
    482465     * Allocate and initialize a URB queue structure.
    483466     */
     
    543526
    544527        RTCritSectEnter(&pPriv->CritSect);
    545         pUrb->Dev.pvPrivate = pQUrbWin;
    546         pPriv->aPendingUrbs[pPriv->cPendingUrbs] = pQUrbWin;
    547         pPriv->cPendingUrbs++;
     528        do
     529        {
     530            /* Ensure we've got sufficient space in the arrays.
     531             * Do it inside the lock to ensure we do not concur
     532             * with the usbProxyWinAsyncIoThread */
     533            if (pPriv->cQueuedUrbs + 1 > pPriv->cAllocatedUrbs)
     534            {
     535                unsigned cNewMax = pPriv->cAllocatedUrbs + 32;
     536                void *pv = RTMemRealloc(pPriv->paHandles, sizeof(pPriv->paHandles[0]) * cNewMax);
     537                if (!pv)
     538                {
     539                    AssertMsgFailed(("RTMemRealloc failed for paHandles[%d]", cNewMax));
     540                    break;
     541                }
     542                pPriv->paHandles = (PHANDLE)pv;
     543
     544                pv = RTMemRealloc(pPriv->paQueuedUrbs, sizeof(pPriv->paQueuedUrbs[0]) * cNewMax);
     545                if (!pv)
     546                {
     547                    AssertMsgFailed(("RTMemRealloc failed for paQueuedUrbs[%d]", cNewMax));
     548                    break;
     549                }
     550                pPriv->paQueuedUrbs = (PQUEUED_URB *)pv;
     551                pPriv->cAllocatedUrbs = cNewMax;
     552            }
     553
     554            pUrb->Dev.pvPrivate = pQUrbWin;
     555            pPriv->aPendingUrbs[pPriv->cPendingUrbs] = pQUrbWin;
     556            pPriv->cPendingUrbs++;
     557            RTCritSectLeave(&pPriv->CritSect);
     558            SetEvent(pPriv->hEventAsyncIo);
     559            return true;
     560        } while (0);
     561
    548562        RTCritSectLeave(&pPriv->CritSect);
    549         SetEvent(pPriv->hEventAsyncIo);
    550         return true;
    551     }
    552     Assert(pPriv->cPendingUrbs < RT_ELEMENTS(pPriv->aPendingUrbs));
     563    }
     564#ifdef DEBUG_misha
     565    else
     566    {
     567        AssertMsgFailed((__FUNCTION__": FAILED!!\n"));
     568    }
     569#endif
     570
     571    Assert(pQUrbWin->overlapped.hEvent == INVALID_HANDLE_VALUE);
    553572    RTMemFree(pQUrbWin);
    554573    return false;
     
    620639    unsigned cQueuedUrbs = ASMAtomicReadU32((volatile uint32_t *)&pPriv->cQueuedUrbs);
    621640
     641    /* we assume here
     642     * 1. the usbProxyWinUrbReap can not be run concurrently with each other so racing the cQueuedUrbs access/modification can not occur
     643     * 2. the usbProxyWinUrbReap can not be run concurrently with usbProxyWinUrbQueue so they can not race the pPriv->paHandles access/realloc */
    622644    DWORD rc = WaitForMultipleObjects(cQueuedUrbs, pPriv->paHandles, FALSE, cMillies);
    623645    if (rc >= WAIT_OBJECT_0 && rc < WAIT_OBJECT_0 + cQueuedUrbs)
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