VirtualBox

Changeset 41528 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
May 31, 2012 4:48:33 PM (13 years ago)
Author:
vboxsync
Message:

Main/HostUSBDevice(all platforms)+USBProxyService: redo USB locking, fixes major regression, added lots of assertions to catch locking flaws early, whitespace cleanup
Main/Machine: small USB locking fix to be consistent with the remaining code
Main/Host+glue/AutoLock: replace USB list lock by host lock, small numbering cleanup
Main/Console: redo USB locking, do less in USB callbacks/EMT (addresses long standing todo items), eliminate unsafe iterator parameters

Location:
trunk/src/VBox/Main
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/glue/AutoLock.cpp

    r40452 r41528  
    6666    } aClasses[] =
    6767    {
    68         { LOCKCLASS_VIRTUALBOXOBJECT,   "1-VIRTUALBOXOBJECT" },
     68        { LOCKCLASS_VIRTUALBOXOBJECT,   "2-VIRTUALBOXOBJECT" },
    6969        { LOCKCLASS_HOSTOBJECT,         "3-HOSTOBJECT" },
    7070        { LOCKCLASS_LISTOFMACHINES,     "4-LISTOFMACHINES" },
     
    7575        { LOCKCLASS_LISTOFOTHEROBJECTS, "9-LISTOFOTHEROBJECTS" },
    7676        { LOCKCLASS_OTHEROBJECT,        "10-OTHEROBJECT" },
    77         { LOCKCLASS_USBLIST,            "11-USBLIST" },
    78         { LOCKCLASS_PROGRESSLIST,       "12-PROGRESSLIST" },
    79         { LOCKCLASS_OBJECTSTATE,        "13-OBJECTSTATE" }
     77        { LOCKCLASS_PROGRESSLIST,       "11-PROGRESSLIST" },
     78        { LOCKCLASS_OBJECTSTATE,        "12-OBJECTSTATE" }
    8079    };
    8180
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r41352 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2011 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    602602#ifdef VBOX_WITH_USB
    603603    HRESULT attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs);
    604     HRESULT detachUSBDevice(USBDeviceList::iterator &aIt);
     604    HRESULT detachUSBDevice(const ComObjPtr<OUSBDevice> &aHostDevice);
    605605
    606606    static DECLCALLBACK(int) usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid,
    607                        bool aRemote, const char *aAddress, ULONG aMaskedIfs);
    608     static DECLCALLBACK(int) usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid);
     607                       bool aRemote, const char *aAddress, void *pvRemoteBackend, USHORT aPortVersion, ULONG aMaskedIfs);
     608    static DECLCALLBACK(int) usbDetachCallback(Console *that, PVM pVM, PCRTUUID aUuid);
    609609#endif
    610610
  • trunk/src/VBox/Main/include/USBProxyService.h

    r37618 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    7979    virtual int captureDevice(HostUSBDevice *aDevice);
    8080    virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
     81    /** @todo unused */
    8182    virtual void detachingDevice(HostUSBDevice *aDevice);
    8283    virtual int releaseDevice(HostUSBDevice *aDevice);
     
    160161    virtual int captureDevice(HostUSBDevice *aDevice);
    161162    virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
     163    /** @todo unused */
    162164    virtual void detachingDevice(HostUSBDevice *aDevice);
    163165    virtual int releaseDevice(HostUSBDevice *aDevice);
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r41474 r41528  
    30093009            Guid(aId).raw());
    30103010
     3011    /* Remove the device from the collection, it is re-added below for failures */
     3012    mUSBDevices.erase(it);
     3013
    30113014    /*
    30123015     * Inform the USB device and USB proxy about what's cooking.
    30133016     */
    30143017    alock.release();
    3015     HRESULT rc2 = mControl->DetachUSBDevice(aId, false /* aDone */);
    3016     if (FAILED(rc2))
    3017         return rc2;
    3018     alock.acquire();
     3018    HRESULT rc = mControl->DetachUSBDevice(aId, false /* aDone */);
     3019    if (FAILED(rc))
     3020    {
     3021        /* Re-add the device to the collection */
     3022        alock.acquire();
     3023        mUSBDevices.push_back(pUSBDevice);
     3024        return rc;
     3025    }
    30193026
    30203027    /* Request the PDM to detach the USB device. */
    3021     HRESULT rc = detachUSBDevice(it);
    3022 
     3028    rc = detachUSBDevice(pUSBDevice);
    30233029    if (SUCCEEDED(rc))
    30243030    {
    3025         /* release the lock since we don't need it any more (note though that
    3026          * the USB Proxy service must not call us back here) */
    3027         alock.release();
    3028 
    30293031        /* Request the device release. Even if it fails, the device will
    30303032         * remain as held by proxy, which is OK for us (the VM process). */
    30313033        rc = mControl->DetachUSBDevice(aId, true /* aDone */);
     3034    }
     3035    else
     3036    {
     3037        /* Re-add the device to the collection */
     3038        alock.acquire();
     3039        mUSBDevices.push_back(pUSBDevice);
    30323040    }
    30333041
     
    49965004    if (aError != NULL)
    49975005    {
     5006        /* notify callbacks about the error */
    49985007        alock.release();
    4999         /* notify callbacks about the error */
    50005008        onUSBDeviceStateChange(aDevice, true /* aAttached */, aError);
    50015009        return S_OK;
     
    50105018
    50115019    alock.release();
    5012 
    50135020    HRESULT rc = attachUSBDevice(aDevice, aMaskedIfs);
    50145021    if (FAILED(rc))
     
    50875094    }
    50885095
    5089     alock.release();
    5090 
    50915096    if (aError != NULL)
    50925097    {
    50935098        /* notify callback about an error */
     5099        alock.release();
    50945100        onUSBDeviceStateChange(pUSBDevice, false /* aAttached */, aError);
    50955101        return S_OK;
    50965102    }
    50975103
    5098     HRESULT rc = detachUSBDevice(it);
    5099 
     5104    /* Remove the device from the collection, it is re-added below for failures */
     5105    mUSBDevices.erase(it);
     5106
     5107    alock.release();
     5108    HRESULT rc = detachUSBDevice(pUSBDevice);
    51005109    if (FAILED(rc))
    51015110    {
     5111        /* Re-add the device to the collection */
     5112        alock.acquire();
     5113        mUSBDevices.push_back(pUSBDevice);
     5114        alock.release();
    51025115        /* take the current error info */
    51035116        com::ErrorInfoKeeper eik;
     
    76257638 *
    76267639 * @note Synchronously calls EMT.
    7627  * @note Must be called from under this object's lock.
    76287640 */
    76297641HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs)
    76307642{
    76317643    AssertReturn(aHostDevice, E_FAIL);
    7632     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
     7644    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
    76337645
    76347646    HRESULT hrc;
     
    76617673                      Address.c_str(), uuid.raw()));
    76627674
    7663 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
     7675    void *pvRemoteBackend = NULL;
     7676    if (fRemote)
     7677    {
     7678        RemoteUSBDevice *pRemoteUSBDevice = static_cast<RemoteUSBDevice *>(aHostDevice);
     7679        pvRemoteBackend = consoleVRDPServer()->USBBackendRequestPointer(pRemoteUSBDevice->clientId(), &uuid);
     7680        if (!pvRemoteBackend)
     7681            return E_INVALIDARG; /* The clientId is invalid then. */
     7682    }
     7683
     7684    USHORT portVersion = 1;
     7685    hrc = aHostDevice->COMGETTER(PortVersion)(&portVersion);
     7686    AssertComRCReturnRC(hrc);
     7687    Assert(portVersion == 1 || portVersion == 2);
     7688
    76647689    int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
    7665                               (PFNRT)usbAttachCallback, 7,
    7666                               this, ptrVM.raw(), aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
    7667 
    7668     /* hrc is S_OK here */
    7669 
    7670     if (RT_FAILURE(vrc))
     7690                              (PFNRT)usbAttachCallback, 9,
     7691                              this, ptrVM.raw(), aHostDevice, uuid.raw(), fRemote, Address.c_str(), pvRemoteBackend, portVersion, aMaskedIfs);
     7692
     7693    if (RT_SUCCESS(vrc))
     7694    {
     7695        /* Create a OUSBDevice and add it to the device list */
     7696        ComObjPtr<OUSBDevice> pUSBDevice;
     7697        pUSBDevice.createObject();
     7698        hrc = pUSBDevice->init(aHostDevice);
     7699        AssertComRC(hrc);
     7700
     7701        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     7702        mUSBDevices.push_back(pUSBDevice);
     7703        LogFlowFunc(("Attached device {%RTuuid}\n", pUSBDevice->id().raw()));
     7704
     7705        /* notify callbacks */
     7706        alock.release();
     7707        onUSBDeviceStateChange(pUSBDevice, true /* aAttached */, NULL);
     7708    }
     7709    else
    76717710    {
    76727711        LogWarningThisFunc(("Failed to create proxy device for '%s' {%RTuuid} (%Rrc)\n",
     
    77057744//static
    77067745DECLCALLBACK(int)
    7707 Console::usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
     7746Console::usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, void *pvRemoteBackend, USHORT aPortVersion, ULONG aMaskedIfs)
    77087747{
    77097748    LogFlowFuncEnter();
    7710     LogFlowFunc(("that={%p}\n", that));
     7749    LogFlowFunc(("that={%p} aUuid={%RTuuid}\n", that, aUuid));
    77117750
    77127751    AssertReturn(that && aUuid, VERR_INVALID_PARAMETER);
    7713 
    7714     void *pvRemoteBackend = NULL;
    7715     if (aRemote)
    7716     {
    7717         RemoteUSBDevice *pRemoteUSBDevice = static_cast<RemoteUSBDevice *>(aHostDevice);
    7718         Guid guid(*aUuid);
    7719 
    7720         pvRemoteBackend = that->consoleVRDPServer()->USBBackendRequestPointer(pRemoteUSBDevice->clientId(), &guid);
    7721         if (!pvRemoteBackend)
    7722             return VERR_INVALID_PARAMETER; /* The clientId is invalid then. */
    7723     }
    7724 
    7725     USHORT portVersion = 1;
    7726     HRESULT hrc = aHostDevice->COMGETTER(PortVersion)(&portVersion);
    7727     AssertComRCReturn(hrc, VERR_GENERAL_FAILURE);
    7728     Assert(portVersion == 1 || portVersion == 2);
     7752    AssertReturn(!that->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
    77297753
    77307754    int vrc = PDMR3USBCreateProxyDevice(pVM, aUuid, aRemote, aAddress, pvRemoteBackend,
    7731                                         portVersion == 1 ? VUSB_STDVER_11 : VUSB_STDVER_20, aMaskedIfs);
    7732     if (RT_SUCCESS(vrc))
    7733     {
    7734         /* Create a OUSBDevice and add it to the device list */
    7735         ComObjPtr<OUSBDevice> pUSBDevice;
    7736         pUSBDevice.createObject();
    7737         hrc = pUSBDevice->init(aHostDevice);
    7738         AssertComRC(hrc);
    7739 
    7740         AutoWriteLock alock(that COMMA_LOCKVAL_SRC_POS);
    7741         that->mUSBDevices.push_back(pUSBDevice);
    7742         LogFlowFunc(("Attached device {%RTuuid}\n", pUSBDevice->id().raw()));
    7743 
    7744         alock.release();
    7745 
    7746         /* notify callbacks */
    7747         that->onUSBDeviceStateChange(pUSBDevice, true /* aAttached */, NULL);
    7748     }
    7749 
     7755                                        aPortVersion == 1 ? VUSB_STDVER_11 : VUSB_STDVER_20, aMaskedIfs);
    77507756    LogFlowFunc(("vrc=%Rrc\n", vrc));
    77517757    LogFlowFuncLeave();
     
    77587764 * collection.
    77597765 *
    7760  * @param aIt  Iterator pointing to the device to detach.
     7766 * @param aHostDevice  device to attach
    77617767 *
    77627768 * @note Synchronously calls EMT.
    7763  * @note Must be called from under this object's lock.
    77647769 */
    7765 HRESULT Console::detachUSBDevice(USBDeviceList::iterator &aIt)
    7766 {
    7767     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
     7770HRESULT Console::detachUSBDevice(const ComObjPtr<OUSBDevice> &aHostDevice)
     7771{
     7772    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
    77687773
    77697774    /* Get the VM handle. */
     
    77757780    AssertReturn(PDMR3USBHasHub(ptrVM), E_FAIL);
    77767781
     7782    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    77777783    LogFlowThisFunc(("Detaching USB proxy device {%RTuuid}...\n",
    7778                      (*aIt)->id().raw()));
    7779 
    7780 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
     7784                     aHostDevice->id().raw()));
     7785
     7786    /*
     7787     * If this was a remote device, release the backend pointer.
     7788     * The pointer was requested in usbAttachCallback.
     7789     */
     7790    BOOL fRemote = FALSE;
     7791
     7792    HRESULT hrc2 = aHostDevice->COMGETTER(Remote)(&fRemote);
     7793    if (FAILED(hrc2))
     7794        setErrorStatic(hrc2, "GetRemote() failed");
     7795
     7796    PCRTUUID pUuid = aHostDevice->id().raw();
     7797    if (fRemote)
     7798    {
     7799        Guid guid(*pUuid);
     7800        consoleVRDPServer()->USBBackendReleasePointer(&guid);
     7801    }
     7802
     7803    alock.release();
    77817804    int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
    77827805                              (PFNRT)usbDetachCallback, 5,
    7783                               this, ptrVM.raw(), &aIt, (*aIt)->id().raw());
     7806                              this, ptrVM.raw(), pUuid);
     7807    if (RT_SUCCESS(vrc))
     7808    {
     7809        LogFlowFunc(("Detached device {%RTuuid}\n", pUuid));
     7810
     7811        /* notify callbacks */
     7812        onUSBDeviceStateChange(aHostDevice, false /* aAttached */, NULL);
     7813    }
     7814
    77847815    ComAssertRCRet(vrc, E_FAIL);
    77857816
     
    77947825 *
    77957826 * @thread EMT
    7796  * @note Locks the console object for writing.
    77977827 */
    77987828//static
    77997829DECLCALLBACK(int)
    7800 Console::usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
     7830Console::usbDetachCallback(Console *that, PVM pVM, PCRTUUID aUuid)
    78017831{
    78027832    LogFlowFuncEnter();
    7803     LogFlowFunc(("that={%p}\n", that));
     7833    LogFlowFunc(("that={%p} aUuid={%RTuuid}\n", that, aUuid));
    78047834
    78057835    AssertReturn(that && aUuid, VERR_INVALID_PARAMETER);
    7806     ComObjPtr<OUSBDevice> pUSBDevice = **aIt;
    7807 
    7808     /*
    7809      * If that was a remote device, release the backend pointer.
    7810      * The pointer was requested in usbAttachCallback.
    7811      */
    7812     BOOL fRemote = FALSE;
    7813 
    7814     HRESULT hrc2 = (**aIt)->COMGETTER(Remote)(&fRemote);
    7815     if (FAILED(hrc2))
    7816         setErrorStatic(hrc2, "GetRemote() failed");
    7817 
    7818     if (fRemote)
    7819     {
    7820         Guid guid(*aUuid);
    7821         that->consoleVRDPServer()->USBBackendReleasePointer(&guid);
    7822     }
     7836    AssertReturn(!that->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
    78237837
    78247838    int vrc = PDMR3USBDetachDevice(pVM, aUuid);
    7825 
    7826     if (RT_SUCCESS(vrc))
    7827     {
    7828         AutoWriteLock alock(that COMMA_LOCKVAL_SRC_POS);
    7829 
    7830         /* Remove the device from the collection */
    7831         that->mUSBDevices.erase(*aIt);
    7832         LogFlowFunc(("Detached device {%RTuuid}\n", pUSBDevice->id().raw()));
    7833 
    7834         alock.release();
    7835 
    7836         /* notify callbacks */
    7837         that->onUSBDeviceStateChange(pUSBDevice, false /* aAttached */, NULL);
    7838     }
    78397839
    78407840    LogFlowFunc(("vrc=%Rrc\n", vrc));
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r41174 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2011 Oracle Corporation
     7 * Copyright (C) 2004-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    173173    Data()
    174174        :
    175 #ifdef VBOX_WITH_USB
    176           usbListsLock(LOCKCLASS_USBLIST),
    177 #endif
    178175          fDVDDrivesListBuilt(false),
    179176          fFloppyDrivesListBuilt(false)
     
    183180
    184181#ifdef VBOX_WITH_USB
    185     WriteLockHandle         usbListsLock;               // protects the below two lists
    186 
    187182    USBDeviceFilterList     llChildren;                 // all USB device filters
    188183    USBDeviceFilterList     llUSBDeviceFilters;         // USB device filters in use by the USB proxy service
     
    779774    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    780775
    781     AutoMultiWriteLock2 alock(this->lockHandle(), &m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     776    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    782777
    783778    HRESULT rc = checkUSBProxyService();
     
    12291224    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    12301225
    1231     AutoMultiWriteLock2 alock(this->lockHandle(), &m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     1226    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    12321227
    12331228    clearError();
     
    12911286    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    12921287
    1293     AutoMultiWriteLock2 alock(this->lockHandle(), &m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     1288    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    12941289
    12951290    clearError();
     
    15681563    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    15691564
    1570     AutoMultiWriteLock2 alock(this->lockHandle(), &m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     1565    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    15711566
    15721567    for (settings::USBDeviceFiltersList::const_iterator it = data.llUSBDeviceFilters.begin();
     
    16021597    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    16031598
    1604     AutoReadLock alock1(this COMMA_LOCKVAL_SRC_POS);
    1605     AutoReadLock alock2(&m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     1599    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    16061600
    16071601    data.llUSBDeviceFilters.clear();
     
    20102004    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    20112005
    2012     AutoWriteLock alock(&m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     2006    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    20132007
    20142008    m->llChildren.push_back(pChild);
     
    20222016    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    20232017
    2024     AutoWriteLock alock(&m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     2018    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    20252019
    20262020    for (USBDeviceFilterList::iterator it = m->llChildren.begin();
     
    21022096void Host::getUSBFilters(Host::USBDeviceFilterList *aGlobalFilters)
    21032097{
    2104     AutoReadLock alock(&m->usbListsLock COMMA_LOCKVAL_SRC_POS);
     2098    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    21052099
    21062100    *aGlobalFilters = m->llUSBDeviceFilters;
  • trunk/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp

    r40257 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333/////////////////////////////////////////////////////////////////////////////
    3434
    35 DEFINE_EMPTY_CTOR_DTOR (HostUSBDevice)
     35DEFINE_EMPTY_CTOR_DTOR(HostUSBDevice)
    3636
    3737HRESULT HostUSBDevice::FinalConstruct()
     
    114114    if (mUsb != NULL)
    115115    {
    116         USBProxyService::freeDevice (mUsb);
     116        USBProxyService::freeDevice(mUsb);
    117117        mUsb = NULL;
    118118    }
     
    189189    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    190190
    191     Bstr (mUsb->pszManufacturer).cloneTo(aManufacturer);
     191    Bstr(mUsb->pszManufacturer).cloneTo(aManufacturer);
    192192
    193193    return S_OK;
     
    203203    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    204204
    205     Bstr (mUsb->pszProduct).cloneTo(aProduct);
     205    Bstr(mUsb->pszProduct).cloneTo(aProduct);
    206206
    207207    return S_OK;
     
    217217    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    218218
    219     Bstr (mUsb->pszSerialNumber).cloneTo(aSerialNumber);
     219    Bstr(mUsb->pszSerialNumber).cloneTo(aSerialNumber);
    220220
    221221    return S_OK;
     
    231231    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    232232
    233     Bstr (mUsb->pszAddress).cloneTo(aAddress);
     233    Bstr(mUsb->pszAddress).cloneTo(aAddress);
    234234
    235235    return S_OK;
     
    305305/////////////////////////////////////////////////////////////////////////////
    306306
    307 STDMETHODIMP HostUSBDevice::COMGETTER(State) (USBDeviceState_T *aState)
     307STDMETHODIMP HostUSBDevice::COMGETTER(State)(USBDeviceState_T *aState)
    308308{
    309309    CheckComArgOutPointerValid(aState);
     
    331331
    332332    AutoCaller autoCaller(this);
    333     AssertComRCReturn (autoCaller.rc(), name);
     333    AssertComRCReturn(autoCaller.rc(), name);
    334334
    335335    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    338338    bool haveProduct = mUsb->pszProduct && *mUsb->pszProduct;
    339339    if (haveManufacturer && haveProduct)
    340         name = Utf8StrFmt ("%s %s", mUsb->pszManufacturer, mUsb->pszProduct);
     340        name = Utf8StrFmt("%s %s", mUsb->pszManufacturer, mUsb->pszProduct);
    341341    else if (haveManufacturer)
    342         name = Utf8StrFmt ("%s", mUsb->pszManufacturer);
     342        name = Utf8StrFmt("%s", mUsb->pszManufacturer);
    343343    else if (haveProduct)
    344         name = Utf8StrFmt ("%s", mUsb->pszProduct);
     344        name = Utf8StrFmt("%s", mUsb->pszProduct);
    345345    else
    346346        name = "<unknown>";
     
    365365 * @retval  E_UNEXPECTED if the device state doesn't permit for any attaching.
    366366 * @retval  E_* as appropriate.
    367  *
    368  * @note   Must be called from under the object write lock.
    369  * @note   May lock the given machine object for reading.
    370367 */
    371368HRESULT HostUSBDevice::requestCaptureForVM(SessionMachine *aMachine, bool aSetError, ULONG aMaskedIfs /* = 0*/)
    372369{
     370    /*
     371     * Validate preconditions and input.
     372     */
     373    AssertReturn(aMachine, E_INVALIDARG);
     374    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
     375    AssertReturn(!aMachine->isWriteLockOnCurrentThread(), E_FAIL);
     376
     377    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    373378    LogFlowThisFunc(("{%s} aMachine=%p aMaskedIfs=%#x\n", mName, aMachine, aMaskedIfs));
    374379
    375     /*
    376      * Validate preconditions and input.
    377      */
    378     AssertReturn(aMachine, E_INVALIDARG);
    379     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    380380    if (aSetError)
    381381    {
     
    391391        {
    392392            /* Machine::name() requires a read lock */
     393            alock.release();
    393394            AutoReadLock machLock(mMachine COMMA_LOCKVAL_SRC_POS);
    394395            return setError(E_INVALIDARG,
     
    420421    if (mUniState == kHostUSBDeviceState_HeldByProxy)
    421422    {
     423        alock.release();
    422424        HRESULT hrc = attachToVM(aMachine, aMaskedIfs);
    423425        return SUCCEEDED(hrc);
     
    439441    mMachine = aMachine;
    440442    mMaskedIfs = aMaskedIfs;
     443    alock.release();
    441444    int rc = mUSBProxyService->captureDevice(this);
    442445    if (RT_FAILURE(rc))
    443446    {
     447        alock.acquire();
    444448        failTransition();
    445449        mMachine.setNull();
     
    473477HRESULT HostUSBDevice::attachToVM(SessionMachine *aMachine, ULONG aMaskedIfs /* = 0*/)
    474478{
     479    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
     480    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    475481    /*
    476482     * Validate and update the state.
     
    487493    ComPtr<IUSBDevice> d = this;
    488494
    489     AutoWriteLock alockSelf(this COMMA_LOCKVAL_SRC_POS);
    490     alockSelf.release();
    491     AutoWriteLock alockProxy(mUSBProxyService COMMA_LOCKVAL_SRC_POS);
    492     alockProxy.release();
    493 
    494495    /*
    495496     * Call the VM process (IPC) and request it to attach the device.
     
    500501     */
    501502    LogFlowThisFunc(("{%s} Calling machine->onUSBDeviceAttach()...\n", mName));
    502     HRESULT hrc = aMachine->onUSBDeviceAttach (d, NULL, aMaskedIfs);
     503    alock.release();
     504    HRESULT hrc = aMachine->onUSBDeviceAttach(d, NULL, aMaskedIfs);
    503505    LogFlowThisFunc(("{%s} Done machine->onUSBDeviceAttach()=%08X\n", mName, hrc));
    504506
     
    507509     * physically detached while we were busy.
    508510     */
    509     alockProxy.acquire();
    510     alockSelf.acquire();
     511    alock.acquire();
    511512
    512513    if (SUCCEEDED(hrc))
     
    517518        else
    518519        {
     520            alock.release();
    519521            detachFromVM(kHostUSBDeviceState_PhysDetached);
    520522            hrc = E_UNEXPECTED;
     
    532534        else
    533535        {
     536            alock.release();
    534537            onPhysicalDetachedInternal();
    535538            hrc = E_UNEXPECTED;
     
    556559     */
    557560    Assert(aFinalState == kHostUSBDeviceState_PhysDetached);
     561    AssertReturnVoid(!isWriteLockOnCurrentThread());
     562    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    558563    Assert(   mUniState == kHostUSBDeviceState_AttachingToVM
    559564           || mUniState == kHostUSBDeviceState_UsedByVM);
     
    566571     */
    567572    setState(kHostUSBDeviceState_PhysDetachingFromVM, kHostUSBDeviceState_PhysDetached);
    568     AutoWriteLock alockSelf(this COMMA_LOCKVAL_SRC_POS);
    569     alockSelf.release();
    570     AutoWriteLock alockProxy(mUSBProxyService COMMA_LOCKVAL_SRC_POS);
    571     alockProxy.release();
    572573
    573574    /*
     
    578579     * out of people.
    579580     */
     581    alock.release();
    580582    LogFlowThisFunc(("{%s} Calling machine->onUSBDeviceDetach()...\n", mName));
    581583    HRESULT hrc = mMachine->onUSBDeviceDetach(mId.toUtf16().raw(), NULL);
     
    586588     * Re-acquire the locks and complete the transition.
    587589     */
    588     alockProxy.acquire();
    589     alockSelf.acquire();
     590    alock.acquire();
    590591    advanceTransition();
    591592}
     
    672673 * @retval  E_* as appropriate.
    673674 *
    674  * @note Must be called from under the object write lock.
     675 * @note Must be called without holding the object lock.
    675676 */
    676677HRESULT HostUSBDevice::requestReleaseToHost()
    677678{
     679    /*
     680     * Validate preconditions.
     681     */
     682    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
     683    Assert(mMachine.isNull());
     684
     685    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    678686    LogFlowThisFunc(("{%s}\n", mName));
    679 
    680     /*
    681      * Validate preconditions.
    682      */
    683     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    684     Assert(mMachine.isNull());
    685687    if (    mUniState == kHostUSBDeviceState_Unused
    686688        ||  mUniState == kHostUSBDeviceState_Capturable)
     
    697699    startTransition(kHostUSBDeviceState_ReleasingToHost, kHostUSBDeviceState_Unused);
    698700#endif
     701    alock.release();
    699702    int rc = mUSBProxyService->releaseDevice(this);
    700703    if (RT_FAILURE(rc))
    701704    {
     705        alock.acquire();
    702706        failTransition();
    703707        return E_FAIL;
     
    718722 * @retval  E_* as appropriate.
    719723 *
    720  * @note Must be called from under the object write lock.
     724 * @note Must be called without holding the object lock.
    721725 */
    722726HRESULT HostUSBDevice::requestHold()
    723727{
     728    /*
     729     * Validate preconditions.
     730     */
     731    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
     732    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    724733    LogFlowThisFunc(("{%s}\n", mName));
    725 
    726     /*
    727      * Validate preconditions.
    728      */
    729     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    730734    AssertMsgReturn(   mUniState == kHostUSBDeviceState_Unused
    731735                    || mUniState == kHostUSBDeviceState_Capturable
     
    749753    startTransition(kHostUSBDeviceState_Capturing, kHostUSBDeviceState_HeldByProxy);
    750754#endif
     755    alock.release();
    751756    int rc = mUSBProxyService->captureDevice(this);
    752757    if (RT_FAILURE(rc))
    753758    {
     759        alock.acquire();
    754760        failTransition();
    755761        return E_FAIL;
     
    796802#ifndef RT_OS_WINDOWS /* check the implementation details here. */
    797803                    uint64_t elapsedNanoseconds = RTTimeNanoTS() - mLastStateChangeTS;
    798                     if (elapsedNanoseconds > UINT64_C (60000000000) ) /* 60 seconds */
     804                    if (elapsedNanoseconds > UINT64_C(60000000000)) /* 60 seconds */
    799805                    {
    800                         LogRel (("USB: Async operation timed out for device %s (state: %s)\n", mName, getStateName()));
     806                        LogRel(("USB: Async operation timed out for device %s (state: %s)\n", mName, getStateName()));
    801807                        failTransition();
    802808                    }
     
    823829
    824830        default:
    825             AssertLogRelMsgFailed (("this=%p %s\n", this, getStateName()));
     831            AssertLogRelMsgFailed(("this=%p %s\n", this, getStateName()));
    826832            break;
    827833    }
     
    838844 *
    839845 * Otherwise the device will be detached from any VM currently using it - this
    840  * involves IPC and will temporarily abandond locks - and all the device data
     846 * involves IPC and will temporarily abandon locks - and all the device data
    841847 * reset.
    842  *
    843  * @note Must be called from under the object write lock.
    844848 */
    845849void HostUSBDevice::onPhysicalDetached()
    846850{
     851    AssertReturnVoid(!isWriteLockOnCurrentThread());
     852    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    847853    LogFlowThisFunc(("{%s}\n", mName));
    848     AssertReturnVoid(isWriteLockOnCurrentThread());
    849854
    850855    mIsPhysicallyDetached = true;
    851856    if (mUniState < kHostUSBDeviceState_FirstTransitional)
     857    {
     858        alock.release();
    852859        onPhysicalDetachedInternal();
     860    }
    853861}
    854862
     
    859867 *
    860868 * See onPhysicalDetach() for details.
    861  *
    862  * @note Must be called from under the object write lock.
    863869 */
    864870void HostUSBDevice::onPhysicalDetachedInternal()
    865871{
     872    AssertReturnVoid(!isWriteLockOnCurrentThread());
     873    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    866874    LogFlowThisFunc(("{%s}\n", mName));
    867     AssertReturnVoid(isWriteLockOnCurrentThread());
    868875    Assert(mIsPhysicallyDetached);
    869876
     
    874881        &&  (   mUniState == kHostUSBDeviceState_UsedByVM
    875882             || mUniState == kHostUSBDeviceState_AttachingToVM))
     883    {
     884        alock.release();
    876885        detachFromVM(kHostUSBDeviceState_PhysDetached);
     886        alock.acquire();
     887    }
    877888    else
    878889        AssertMsg(mMachine.isNull(), ("%s\n", getStateName()));
     
    10611072 * @returns Whether the Host object should be bothered with this state change.
    10621073 *
    1063  * @note    Locks this object for writing.
    1064  *
    10651074 * @todo    Just do everything here, that is, call filter runners and everything that
    10661075 *          works by state change. Using 3 return codes/parameters is just plain ugly.
     
    10741083     * Locking.
    10751084     */
    1076     AssertReturn(isWriteLockOnCurrentThread(), false);
     1085    AssertReturn(!isWriteLockOnCurrentThread(), false);
    10771086    AutoCaller autoCaller(this);
    10781087    AssertComRCReturn(autoCaller.rc(), false);
    10791088    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1080 
    10811089
    10821090    /*
     
    11381146        aDev->pNext = mUsb->pNext;
    11391147        aDev->pPrev = mUsb->pPrev;
    1140         USBProxyService::freeDevice (mUsb);
     1148        USBProxyService::freeDevice(mUsb);
    11411149        mUsb = aDev;
    11421150    }
     
    14741482 *
    14751483 * @returns See HostUSBDevice::updateState()
    1476  *
    1477  * @note    Caller must write lock the object.
    14781484 */
    14791485bool HostUSBDevice::updateStateFake(PCUSBDEVICE aDev, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    14801486{
     1487    Assert(!isWriteLockOnCurrentThread());
     1488    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    14811489    const HostUSBDeviceState enmState = mUniState;
    14821490    switch (enmState)
     
    14851493        case kHostUSBDeviceState_ReleasingToHost:
    14861494        {
    1487             Assert(isWriteLockOnCurrentThread());
    1488 
    14891495            *aIgnoreMachine = mUniState == kHostUSBDeviceState_ReleasingToHost ? mMachine : NULL;
    14901496            *aRunFilters = advanceTransition();
     
    15071513            /* Take action if we're supposed to attach it to a VM. */
    15081514            if (mUniState == kHostUSBDeviceState_AttachingToVM)
     1515            {
     1516                alock.release();
    15091517                attachToVM(mMachine, mMaskedIfs);
     1518            }
    15101519            return true;
    15111520        }
    15121521
    15131522        default:
     1523            alock.release();
    15141524            return updateState(aDev, aRunFilters, aIgnoreMachine);
    15151525    }
     
    18071817                    break;
    18081818                default:
    1809                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1810                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1819                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1820                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    18111821            }
    18121822            break;
     
    18351845                            break;
    18361846                        default:
    1837                             AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1838                                                           stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1847                            AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1848                                                         stateName(aNewState, aNewPendingState, aNewSubState)), false);
    18391849                    }
    18401850                    break;
    18411851                default:
    1842                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1843                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1852                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1853                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    18441854            }
    18451855            break;
     
    18641874                            break;
    18651875                        default:
    1866                             AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1867                                                           stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1876                            AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1877                                                         stateName(aNewState, aNewPendingState, aNewSubState)), false);
    18681878                    }
    18691879                    break;
    18701880                default:
    1871                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1872                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1881                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1882                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    18731883            }
    18741884            break;
     
    18931903                            break;
    18941904                        default:
    1895                             AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1896                                                           stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1905                            AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1906                                                         stateName(aNewState, aNewPendingState, aNewSubState)), false);
    18971907                    }
    18981908                    break;
     
    19031913                            break;
    19041914                        default:
    1905                             AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1906                                                           stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1915                            AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1916                                                         stateName(aNewState, aNewPendingState, aNewSubState)), false);
    19071917                    }
    19081918                    break;
    19091919                default:
    1910                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1911                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1920                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1921                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    19121922            }
    19131923            break;
     
    19311941                            break;
    19321942                        default:
    1933                             AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1934                                                           stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1943                            AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1944                                                         stateName(aNewState, aNewPendingState, aNewSubState)), false);
    19351945                    }
    19361946                    break;
    19371947                default:
    1938                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1939                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1948                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1949                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    19401950            }
    19411951            break;
     
    19611971                case kHostUSBDeviceState_UsedByVM:
    19621972                default:
    1963                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    1964                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     1973                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     1974                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    19651975            }
    19661976            break;
     
    20132023
    20142024                default:
    2015                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    2016                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     2025                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     2026                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    20172027            }
    20182028            break;
     
    20572067
    20582068                default:
    2059                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    2060                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     2069                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     2070                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    20612071            }
    20622072            break;
     
    20862096
    20872097                default:
    2088                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    2089                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     2098                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     2099                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    20902100            }
    20912101            break;
     
    21222132
    21232133                default:
    2124                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    2125                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     2134                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     2135                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    21262136            }
    21272137            break;
     
    21392149                    break;
    21402150                default:
    2141                     AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
    2142                                                   stateName(aNewState, aNewPendingState, aNewSubState)), false);
     2151                    AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
     2152                                                 stateName(aNewState, aNewPendingState, aNewSubState)), false);
    21432153            }
    21442154            break;
    21452155
    21462156        default:
    2147             AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
     2157            AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
    21482158    }
    21492159
     
    21682178
    21692179
    2170 
    21712180/**
    21722181 * A convenience for entering a transitional state.
     
    21802189 * @note    The caller must own the write lock for this object.
    21812190 */
    2182 bool HostUSBDevice::startTransition (HostUSBDeviceState aNewState, HostUSBDeviceState aFinalState,
    2183                                      HostUSBDeviceSubState aNewSubState /*= kHostUSBDeviceSubState_Default*/)
    2184 {
     2191bool HostUSBDevice::startTransition(HostUSBDeviceState aNewState, HostUSBDeviceState aFinalState,
     2192                                    HostUSBDeviceSubState aNewSubState /*= kHostUSBDeviceSubState_Default*/)
     2193{
     2194    AssertReturn(isWriteLockOnCurrentThread(), false);
    21852195    /*
    21862196     * A quick prevalidation thing. Not really necessary since setState
     
    22022212        case kHostUSBDeviceState_AttachingToVM:
    22032213        case kHostUSBDeviceState_PhysDetachingFromVM:
    2204             AssertMsgFailedReturn (("this=%p %s is a transitional state.\n", this, getStateName()), false);
     2214            AssertMsgFailedReturn(("this=%p %s is a transitional state.\n", this, getStateName()), false);
    22052215
    22062216        case kHostUSBDeviceState_PhysDetached:
    22072217        default:
    2208             AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
    2209     }
    2210 
    2211     return setState (aNewState, aFinalState, aNewSubState);
     2218            AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
     2219    }
     2220
     2221    return setState(aNewState, aFinalState, aNewSubState);
    22122222}
    22132223
     
    22252235bool HostUSBDevice::advanceTransition(bool aSkipReAttach /* = false */)
    22262236{
     2237    AssertReturn(isWriteLockOnCurrentThread(), false);
    22272238    HostUSBDeviceState enmPending = mPendingUniState;
    22282239    HostUSBDeviceSubState enmSub = mUniSubState;
     
    23862397bool HostUSBDevice::failTransition()
    23872398{
     2399    AssertReturn(isWriteLockOnCurrentThread(), false);
    23882400    HostUSBDeviceSubState enmSub = mUniSubState;
    23892401    HostUSBDeviceState enmState = mUniState;
     
    24122424                    break;
    24132425                default:
    2414                     AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
     2426                    AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
    24152427            }
    24162428            break;
    24172429
    24182430        case kHostUSBDeviceState_PhysDetachingFromVM:
    2419             AssertMsgFailedReturn (("this=%p %s shall not fail\n", this, getStateName()), false);
     2431            AssertMsgFailedReturn(("this=%p %s shall not fail\n", this, getStateName()), false);
    24202432
    24212433        case kHostUSBDeviceState_Unsupported:
     
    24252437        case kHostUSBDeviceState_HeldByProxy:
    24262438        case kHostUSBDeviceState_UsedByVM:
    2427             AssertMsgFailedReturn (("this=%p %s is not transitional\n", this, getStateName()), false);
     2439            AssertMsgFailedReturn(("this=%p %s is not transitional\n", this, getStateName()), false);
    24282440        case kHostUSBDeviceState_PhysDetached:
    24292441        default:
    2430             AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
     2442            AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
    24312443
    24322444    }
     
    25022514        case kHostUSBDeviceState_PhysDetached:
    25032515        default:
    2504             AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), USBDeviceState_NotSupported);
     2516            AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), USBDeviceState_NotSupported);
    25052517    }
    25062518    /* won't ever get here. */
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r41371 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2004-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1267312673 *  filter for the given USB device and @c false otherwise.
    1267412674 *
    12675  *  @note Caller must have requested machine read lock.
     12675 *  @note locks this object for reading.
    1267612676 */
    1267712677bool SessionMachine::hasMatchingUSBFilter(const ComObjPtr<HostUSBDevice> &aDevice, ULONG *aMaskedIfs)
     
    1268312683        return false;
    1268412684
    12685 
    1268612685#ifdef VBOX_WITH_USB
     12686    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     12687
    1268712688    switch (mData->mMachineState)
    1268812689    {
     
    1269412695        /** @todo Live Migration: snapshoting & teleporting. Need to fend things of
    1269512696         *        elsewhere... */
     12697            alock.release();
    1269612698            return mUSBController->hasMatchingFilter(aDevice, aMaskedIfs);
    1269712699        default: break;
  • trunk/src/VBox/Main/src-server/USBProxyService.cpp

    r37599 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    140140    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    141141
    142     SafeIfaceArray<IHostUSBDevice> Collection (mDevices);
     142    SafeIfaceArray<IHostUSBDevice> Collection(mDevices);
    143143    Collection.detachTo(ComSafeArrayOutArg(aUSBDevices));
    144144
     
    181181     * Try to capture the device
    182182     */
    183     AutoWriteLock DevLock(pHostDevice COMMA_LOCKVAL_SRC_POS);
     183    alock.release();
    184184    return pHostDevice->requestCaptureForVM(aMachine, true /* aSetError */);
    185185}
     
    224224    ComObjPtr<HostUSBDevice> pHostDevice = findDeviceById(aId);
    225225    ComAssertRet(!pHostDevice.isNull(), E_FAIL);
    226     AutoWriteLock DevLock(pHostDevice COMMA_LOCKVAL_SRC_POS);
     226    AutoWriteLock devLock(pHostDevice COMMA_LOCKVAL_SRC_POS);
    227227
    228228    /*
     
    241241    {
    242242        Assert(aDone && pHostDevice->getUnistate() == kHostUSBDeviceState_HeldByProxy && pHostDevice->getMachine().isNull());
     243        devLock.release();
     244        alock.release();
    243245        HRESULT hrc2 = runAllFiltersOnDevice(pHostDevice, llOpenedMachines, aMachine);
    244246        ComAssertComRC(hrc2);
     
    265267 * @returns COM status code, perhaps with error info.
    266268 *
    267  * @remarks Write locks the host object and may temporarily abandon
    268  *          its locks to perform IPC.
     269 * @remarks Temporarily locks this object, the machine object and some USB
     270 *          device, and the called methods will lock similar objects.
    269271 */
    270272HRESULT USBProxyService::autoCaptureDevicesForVM(SessionMachine *aMachine)
     
    273275                     aMachine,
    274276                     aMachine->getName().c_str()));
    275     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    276     AutoWriteLock mlock(aMachine COMMA_LOCKVAL_SRC_POS);
    277 
    278     /*
    279      * Make a copy of the list because we might have to exit and
    280      * re-enter the lock protecting it. (This will not make copies
    281      * of any HostUSBDevice objects, only reference them.)
    282      */
     277
     278    /*
     279     * Make a copy of the list because we cannot hold the lock protecting it.
     280     * (This will not make copies of any HostUSBDevice objects, only reference them.)
     281     */
     282    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    283283    HostUSBDeviceList ListCopy = mDevices;
     284    alock.release();
    284285
    285286    for (HostUSBDeviceList::iterator it = ListCopy.begin();
     
    288289    {
    289290        ComObjPtr<HostUSBDevice> device = *it;
    290         AutoWriteLock devLock(device COMMA_LOCKVAL_SRC_POS);
     291        AutoReadLock devLock(device COMMA_LOCKVAL_SRC_POS);
    291292        if (   device->getUnistate() == kHostUSBDeviceState_HeldByProxy
    292293            || device->getUnistate() == kHostUSBDeviceState_Unused
    293294            || device->getUnistate() == kHostUSBDeviceState_Capturable)
     295        {
     296            devLock.release();
    294297            runMachineFilters(aMachine, device);
     298        }
    295299    }
    296300
     
    323327{
    324328    // get a list of all running machines while we're outside the lock
    325     // (getOpenedMachines requests locks which are incompatible with the lock of the machines list)
     329    // (getOpenedMachines requests locks which are incompatible with the host object lock)
    326330    SessionMachinesList llOpenedMachines;
    327331    mHost->parent()->getOpenedMachines(llOpenedMachines);
     
    336340    HostUSBDeviceList ListCopy = mDevices;
    337341
    338     for (HostUSBDeviceList::iterator It = ListCopy.begin();
    339          It != ListCopy.end();
    340          ++It)
    341     {
    342         ComObjPtr<HostUSBDevice> pHostDevice = *It;
     342    for (HostUSBDeviceList::iterator it = ListCopy.begin();
     343         it != ListCopy.end();
     344         ++it)
     345    {
     346        ComObjPtr<HostUSBDevice> pHostDevice = *it;
    343347        AutoWriteLock devLock(pHostDevice COMMA_LOCKVAL_SRC_POS);
    344348        if (pHostDevice->getMachine() == aMachine)
     
    353357            {
    354358                Assert(aDone && pHostDevice->getUnistate() == kHostUSBDeviceState_HeldByProxy && pHostDevice->getMachine().isNull());
     359                devLock.release();
     360                alock.release();
    355361                HRESULT hrc2 = runAllFiltersOnDevice(pHostDevice, llOpenedMachines, aMachine);
    356362                ComAssertComRC(hrc2);
     363                alock.acquire();
    357364            }
    358365        }
     
    382389 *                          detached the device from this machine).
    383390 *
    384  * @note    The caller is expected to own both the device and Host write locks,
    385  *          and be prepared that these locks may be abandond temporarily.
     391 * @note    The caller is expected to own no locks.
    386392 */
    387393HRESULT USBProxyService::runAllFiltersOnDevice(ComObjPtr<HostUSBDevice> &aDevice,
     
    394400     * Verify preconditions.
    395401     */
    396     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    397     AssertReturn(aDevice->isWriteLockOnCurrentThread(), E_FAIL);
     402    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
     403    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), E_FAIL);
     404    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     405    AutoWriteLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    398406    AssertMsgReturn(aDevice->isCapturableOrHeld(), ("{%s} %s\n", aDevice->getName().c_str(), aDevice->getStateName()), E_FAIL);
    399407
     
    406414
    407415    /*
    408      * Run global filters filerts first.
     416     * Run global filters filters first.
    409417     */
    410418    bool fHoldIt = false;
     
    424432                 * Release the device to the host and we're done.
    425433                 */
     434                filterLock.release();
     435                devLock.release();
     436                alock.release();
    426437                aDevice->requestReleaseToHost();
    427438                return S_OK;
     
    456467
    457468        /* runMachineFilters takes care of checking the machine state. */
     469        devLock.release();
     470        alock.release();
    458471        if (runMachineFilters(pMachine, aDevice))
    459472        {
     
    461474            return S_OK;
    462475        }
     476        alock.acquire();
     477        devLock.acquire();
    463478    }
    464479
     
    467482     * on global filter match.
    468483     */
     484    devLock.release();
     485    alock.release();
    469486    if (fHoldIt)
    470487        aDevice->requestHold();
     
    485502 * @returns @c true if the device has been or is being attached to the VM, @c false otherwise.
    486503 *
    487  * @note    Caller must own the USB and device locks for writing.
    488  * @note    Locks aMachine for reading.
     504 * @note    Locks several objects temporarily for reading or writing.
    489505 */
    490506bool USBProxyService::runMachineFilters(SessionMachine *aMachine, ComObjPtr<HostUSBDevice> &aDevice)
     
    496512     */
    497513    AssertReturn(aMachine, false);
    498     AssertReturn(isWriteLockOnCurrentThread(), false);
    499     AssertReturn(aDevice->isWriteLockOnCurrentThread(), false);
     514    AssertReturn(!isWriteLockOnCurrentThread(), false);
     515    AssertReturn(!aMachine->isWriteLockOnCurrentThread(), false);
     516    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    500517    /* Let HostUSBDevice::requestCaptureToVM() validate the state. */
    501518
     
    574591 *
    575592 * @param   aDevice     The device in question.
     593 *
     594 * @todo unused
    576595 */
    577596void USBProxyService::detachingDevice(HostUSBDevice *aDevice)
     
    820839    }
    821840
     841    LogFlowFuncLeave();
    822842    return pHead;
    823843}
     
    840860
    841861    // get a list of all running machines while we're outside the lock
    842     // (getOpenedMachines requests locks which are incompatible with the lock of the machines list)
     862    // (getOpenedMachines requests higher priority locks)
    843863    SessionMachinesList llOpenedMachines;
    844864    mHost->parent()->getOpenedMachines(llOpenedMachines);
     
    847867
    848868    /*
    849      * Compare previous list with the previous list of devices
     869     * Compare previous list with the new list of devices
    850870     * and merge in any changes while notifying Host.
    851871     */
    852     HostUSBDeviceList::iterator It = this->mDevices.begin();
    853     while (    It != mDevices.end()
     872    HostUSBDeviceList::iterator it = this->mDevices.begin();
     873    while (    it != mDevices.end()
    854874            || pDevices)
    855875    {
    856876        ComObjPtr<HostUSBDevice> pHostDevice;
    857877
    858         if (It != mDevices.end())
    859             pHostDevice = *It;
     878        if (it != mDevices.end())
     879            pHostDevice = *it;
    860880
    861881        /*
     
    898918            bool fRunFilters = false;
    899919            SessionMachine *pIgnoreMachine = NULL;
     920            devLock.release();
     921            alock.release();
    900922            if (updateDeviceState(pHostDevice, pCur, &fRunFilters, &pIgnoreMachine))
    901923                deviceChanged(pHostDevice,
    902924                              (fRunFilters ? &llOpenedMachines : NULL),
    903925                              pIgnoreMachine);
    904             It++;
     926            alock.acquire();
     927            it++;
    905928        }
    906929        else
     
    928951                     pNew->pszManufacturer));
    929952
    930                 mDevices.insert(It, NewObj);
    931 
    932                 /* Not really necessary to lock here, but make Assert checks happy. */
    933                 AutoWriteLock newDevLock(NewObj COMMA_LOCKVAL_SRC_POS);
     953                mDevices.insert(it, NewObj);
     954
     955                devLock.release();
     956                alock.release();
    934957                deviceAdded(NewObj, llOpenedMachines, pNew);
     958                alock.acquire();
    935959            }
    936960            else
     
    941965                 */
    942966                if (!pHostDevice->wasActuallyDetached())
    943                     It++;
     967                    it++;
    944968                else
    945969                {
    946                     It = mDevices.erase(It);
     970                    it = mDevices.erase(it);
     971                    devLock.release();
     972                    alock.release();
    947973                    deviceRemoved(pHostDevice);
    948974                    Log(("USBProxyService::processChanges: detached %p {%s}\n",
     
    954980                    devCaller.release();
    955981                    pHostDevice->uninit();
     982                    alock.acquire();
    956983                }
    957984            }
     
    9931020     * Validate preconditions.
    9941021     */
    995     AssertReturnVoid(isWriteLockOnCurrentThread());
    996     AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
     1022    AssertReturnVoid(!isWriteLockOnCurrentThread());
     1023    AssertReturnVoid(!aDevice->isWriteLockOnCurrentThread());
     1024    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    9971025    LogFlowThisFunc(("aDevice=%p name={%s} state=%s id={%RTuuid}\n",
    9981026                     (HostUSBDevice *)aDevice,
     
    10061034    if (aDevice->isCapturableOrHeld())
    10071035    {
     1036        devLock.release();
    10081037        HRESULT rc = runAllFiltersOnDevice(aDevice, llOpenedMachines, NULL /* aIgnoreMachine */);
    10091038        AssertComRC(rc);
     
    10261055     * Validate preconditions.
    10271056     */
    1028     AssertReturnVoid(isWriteLockOnCurrentThread());
    1029     AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
     1057    AssertReturnVoid(!isWriteLockOnCurrentThread());
     1058    AssertReturnVoid(!aDevice->isWriteLockOnCurrentThread());
     1059    AutoWriteLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    10301060    LogFlowThisFunc(("aDevice=%p name={%s} state=%s id={%RTuuid}\n",
    10311061                     (HostUSBDevice *)aDevice,
     
    10381068     * reset all data and uninitialize the device object.
    10391069     */
     1070    devLock.release();
    10401071    aDevice->onPhysicalDetached();
    10411072}
     
    10551086    *aIgnoreMachine = NULL;
    10561087    AssertReturn(aDevice, false);
    1057     AssertReturn(aDevice->isWriteLockOnCurrentThread(), false);
     1088    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    10581089
    10591090    /*
     
    10781109{
    10791110    AssertReturn(aDevice, false);
    1080     AssertReturn(aDevice->isWriteLockOnCurrentThread(), false);
     1111    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    10811112
    10821113    return aDevice->updateState(aUSBDevice, aRunFilters, aIgnoreMachine);
     
    10991130     * Validate preconditions.
    11001131     */
    1101     AssertReturnVoid(isWriteLockOnCurrentThread());
    1102     AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
     1132    AssertReturnVoid(!isWriteLockOnCurrentThread());
     1133    AssertReturnVoid(!aDevice->isWriteLockOnCurrentThread());
     1134    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    11031135    LogFlowThisFunc(("aDevice=%p name={%s} state=%s id={%RTuuid} aRunFilters=%RTbool aIgnoreMachine=%p\n",
    11041136                     (HostUSBDevice *)aDevice,
     
    11081140                     (pllOpenedMachines != NULL),       // used to be "bool aRunFilters"
    11091141                     aIgnoreMachine));
     1142    devLock.release();
    11101143
    11111144    /*
     
    12121245    Guid Id(aId);
    12131246    ComObjPtr<HostUSBDevice> Dev;
    1214     for (HostUSBDeviceList::iterator It = mDevices.begin();
    1215          It != mDevices.end();
    1216          ++It)
    1217         if ((*It)->getId() == Id)
     1247    for (HostUSBDeviceList::iterator it = mDevices.begin();
     1248         it != mDevices.end();
     1249         ++it)
     1250        if ((*it)->getId() == Id)
    12181251        {
    1219             Dev = (*It);
     1252            Dev = (*it);
    12201253            break;
    12211254        }
  • trunk/src/VBox/Main/src-server/darwin/USBProxyServiceDarwin.cpp

    r37599 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3939 * Initialize data members.
    4040 */
    41 USBProxyServiceDarwin::USBProxyServiceDarwin (Host *aHost)
    42     : USBProxyService (aHost), mServiceRunLoopRef (NULL), mNotifyOpaque (NULL), mWaitABitNextTime (false), mUSBLibInitialized (false)
     41USBProxyServiceDarwin::USBProxyServiceDarwin(Host *aHost)
     42    : USBProxyService(aHost), mServiceRunLoopRef(NULL), mNotifyOpaque(NULL), mWaitABitNextTime(false), mUSBLibInitialized(false)
    4343{
    4444    LogFlowThisFunc(("aHost=%p\n", aHost));
     
    101101
    102102#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
    103 void *USBProxyServiceDarwin::insertFilter (PCUSBFILTER aFilter)
    104 {
    105     return USBLibAddFilter (aFilter);
    106 }
    107 
    108 
    109 void USBProxyServiceDarwin::removeFilter (void *aId)
    110 {
    111     USBLibRemoveFilter (aId);
     103void *USBProxyServiceDarwin::insertFilter(PCUSBFILTER aFilter)
     104{
     105    return USBLibAddFilter(aFilter);
     106}
     107
     108
     109void USBProxyServiceDarwin::removeFilter(void *aId)
     110{
     111    USBLibRemoveFilter(aId);
    112112}
    113113#endif /* VBOX_WITH_NEW_USB_CODE_ON_DARWIN */
     
    120120     */
    121121    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
     122    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     123
     124    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    122125    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    123     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     126
    124127    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
    125128
     
    129132     */
    130133    ASMAtomicWriteBool(&mFakeAsync, true);
     134    devLock.release();
    131135    interruptWait();
    132136    return VINF_SUCCESS;
     
    161165void USBProxyServiceDarwin::captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
    162166{
     167    AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
    163168#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
    164169    /*
     
    179184     */
    180185    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
     186    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     187
     188    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    181189    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    182     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     190
    183191    Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
    184192
     
    188196     */
    189197    ASMAtomicWriteBool(&mFakeAsync, true);
     198    devLock.release();
    190199    interruptWait();
    191200    return VINF_SUCCESS;
     
    222231void USBProxyServiceDarwin::releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
    223232{
     233    AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
    224234#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
    225235    /*
     
    234244
    235245
     246/** @todo unused */
    236247void USBProxyServiceDarwin::detachingDevice(HostUSBDevice *aDevice)
    237248{
    238249#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
    239     aDevice->setLogicalReconnect (HostUSBDevice::kDetachingPendingDetach);
     250    aDevice->setLogicalReconnect(HostUSBDevice::kDetachingPendingDetach);
    240251#else
    241252    NOREF(aDevice);
     
    246257bool USBProxyServiceDarwin::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    247258{
     259    AssertReturn(aDevice, false);
     260    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    248261#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
    249262    /* We're faking async state stuff. */
     
    264277#endif
    265278
    266     SInt32 rc = CFRunLoopRunInMode(CFSTR (VBOX_IOKIT_MODE_STRING),
     279    SInt32 rc = CFRunLoopRunInMode(CFSTR(VBOX_IOKIT_MODE_STRING),
    267280                                   mWaitABitNextTime && aMillies >= 1000
    268281                                   ? 1.0 /* seconds */
     
    277290
    278291
    279 int USBProxyServiceDarwin::interruptWait (void)
     292int USBProxyServiceDarwin::interruptWait(void)
    280293{
    281294    if (mServiceRunLoopRef)
    282         CFRunLoopStop (mServiceRunLoopRef);
     295        CFRunLoopStop(mServiceRunLoopRef);
    283296    return 0;
    284297}
    285298
    286299
    287 PUSBDEVICE USBProxyServiceDarwin::getDevices (void)
     300PUSBDEVICE USBProxyServiceDarwin::getDevices(void)
    288301{
    289302    /* call iokit.cpp */
     
    292305
    293306
    294 void USBProxyServiceDarwin::serviceThreadInit (void)
     307void USBProxyServiceDarwin::serviceThreadInit(void)
    295308{
    296309    mServiceRunLoopRef = CFRunLoopGetCurrent();
     
    299312
    300313
    301 void USBProxyServiceDarwin::serviceThreadTerm (void)
    302 {
    303     DarwinUnsubscribeUSBNotifications (mNotifyOpaque);
     314void USBProxyServiceDarwin::serviceThreadTerm(void)
     315{
     316    DarwinUnsubscribeUSBNotifications(mNotifyOpaque);
    304317    mServiceRunLoopRef = NULL;
    305318}
     
    311324 * @param   pCur    The USB device to free.
    312325 */
    313 void DarwinFreeUSBDeviceFromIOKit (PUSBDEVICE pCur)
    314 {
    315     USBProxyService::freeDevice (pCur);
    316 }
    317 
     326void DarwinFreeUSBDeviceFromIOKit(PUSBDEVICE pCur)
     327{
     328    USBProxyService::freeDevice(pCur);
     329}
     330
  • trunk/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp

    r37599 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    111111int USBProxyServiceFreeBSD::captureDevice(HostUSBDevice *aDevice)
    112112{
    113     Log(("USBProxyServiceFreeBSD::captureDevice: %p {%s}\n", aDevice, aDevice->getName().c_str()));
    114113    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
    115     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     114    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     115
     116    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     117    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    116118
    117119    /*
     
    119121     */
    120122    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
     123    devLock.release();
    121124    interruptWait();
    122125
     
    127130int USBProxyServiceFreeBSD::releaseDevice(HostUSBDevice *aDevice)
    128131{
    129     Log(("USBProxyServiceFreeBSD::releaseDevice: %p\n", aDevice));
    130132    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
    131     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     133    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     134
     135    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     136    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    132137
    133138    /*
     
    135140     */
    136141    Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
     142    devLock.release();
    137143    interruptWait();
    138144
     
    143149bool USBProxyServiceFreeBSD::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    144150{
     151    AssertReturn(aDevice, false);
     152    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
     153
    145154    return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
    146155}
     
    148157
    149158/**
    150  * A device was added, we need to adjust mUdevPolls.
     159 * A device was added
    151160 *
    152161 * See USBProxyService::deviceAdded for details.
  • trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp

    r37618 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2011 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    222222int USBProxyServiceLinux::captureDevice(HostUSBDevice *aDevice)
    223223{
    224     Log(("USBProxyServiceLinux::captureDevice: %p {%s}\n", aDevice, aDevice->getName().c_str()));
    225224    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
    226     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     225    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     226
     227    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     228    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    227229
    228230    /*
     
    230232     */
    231233    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
     234    devLock.release();
    232235    interruptWait();
    233236
     
    238241int USBProxyServiceLinux::releaseDevice(HostUSBDevice *aDevice)
    239242{
    240     Log(("USBProxyServiceLinux::releaseDevice: %p\n", aDevice));
    241243    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
    242     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     244    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     245
     246    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     247    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    243248
    244249    /*
     
    246251     */
    247252    Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
     253    devLock.release();
    248254    interruptWait();
    249255
     
    254260bool USBProxyServiceLinux::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    255261{
     262    AssertReturn(aDevice, false);
     263    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
     264    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    256265    if (    aUSBDevice->enmState == USBDEVICESTATE_USED_BY_HOST_CAPTURABLE
    257266        &&  aDevice->mUsb->enmState == USBDEVICESTATE_USED_BY_HOST)
    258267        LogRel(("USBProxy: Device %04x:%04x (%s) has become accessible.\n",
    259268                aUSBDevice->idVendor, aUSBDevice->idProduct, aUSBDevice->pszAddress));
     269    devLock.release();
    260270    return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
    261271}
     
    269279void USBProxyServiceLinux::deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice)
    270280{
     281    AssertReturnVoid(aDevice);
     282    AssertReturnVoid(!aDevice->isWriteLockOnCurrentThread());
     283    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    271284    if (aUSBDevice->enmState == USBDEVICESTATE_USED_BY_HOST)
    272285    {
     
    276289    }
    277290
     291    devLock.release();
    278292    USBProxyService::deviceAdded(aDevice, llOpenedMachines, aUSBDevice);
    279293}
     
    349363int USBProxyServiceLinux::interruptWait(void)
    350364{
     365    AssertReturn(!isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     366
     367    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    351368#ifdef VBOX_USB_WITH_SYSFS
    352369    LogFlowFunc(("mUsingUsbfsDevices=%d\n", mUsingUsbfsDevices));
  • trunk/src/VBox/Main/src-server/os2/USBProxyServiceOs2.cpp

    r31892 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3838 * Initialize data members.
    3939 */
    40 USBProxyServiceOs2::USBProxyServiceOs2 (Host *aHost)
    41     : USBProxyService (aHost), mhev (NULLHANDLE), mhmod (NULLHANDLE),
    42     mpfnUsbRegisterChangeNotification (NULL), mpfnUsbDeregisterNotification (NULL),
    43     mpfnUsbQueryNumberDevices (NULL), mpfnUsbQueryDeviceReport (NULL)
     40USBProxyServiceOs2::USBProxyServiceOs2(Host *aHost)
     41    : USBProxyService(aHost), mhev(NULLHANDLE), mhmod(NULLHANDLE),
     42    mpfnUsbRegisterChangeNotification(NULL), mpfnUsbDeregisterNotification(NULL),
     43    mpfnUsbQueryNumberDevices(NULL), mpfnUsbQueryDeviceReport(NULL)
    4444{
    4545    LogFlowThisFunc(("aHost=%p\n", aHost));
     
    4848     * Try initialize the usbcalls stuff.
    4949     */
    50     int rc = DosCreateEventSem (NULL, &mhev, 0, FALSE);
    51     rc = RTErrConvertFromOS2 (rc);
     50    int rc = DosCreateEventSem(NULL, &mhev, 0, FALSE);
     51    rc = RTErrConvertFromOS2(rc);
    5252    if (RT_SUCCESS(rc))
    5353    {
    54         rc = DosLoadModule (NULL, 0, (PCSZ)"usbcalls", &mhmod);
    55         rc = RTErrConvertFromOS2 (rc);
     54        rc = DosLoadModule(NULL, 0, (PCSZ)"usbcalls", &mhmod);
     55        rc = RTErrConvertFromOS2(rc);
    5656        if (RT_SUCCESS(rc))
    5757        {
    58             if (    (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbQueryNumberDevices",            (PPFN)&mpfnUsbQueryNumberDevices))          == NO_ERROR
    59                 &&  (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbQueryDeviceReport",             (PPFN)&mpfnUsbQueryDeviceReport))           == NO_ERROR
    60                 &&  (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbRegisterChangeNotification",    (PPFN)&mpfnUsbRegisterChangeNotification))  == NO_ERROR
    61                 &&  (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbDeregisterNotification",        (PPFN)&mpfnUsbDeregisterNotification))      == NO_ERROR
     58            if (    (rc = DosQueryProcAddr(mhmod, 0, (PCSZ)"UsbQueryNumberDevices",         (PPFN)&mpfnUsbQueryNumberDevices))          == NO_ERROR
     59                &&  (rc = DosQueryProcAddr(mhmod, 0, (PCSZ)"UsbQueryDeviceReport",          (PPFN)&mpfnUsbQueryDeviceReport))           == NO_ERROR
     60                &&  (rc = DosQueryProcAddr(mhmod, 0, (PCSZ)"UsbRegisterChangeNotification", (PPFN)&mpfnUsbRegisterChangeNotification))  == NO_ERROR
     61                &&  (rc = DosQueryProcAddr(mhmod, 0, (PCSZ)"UsbDeregisterNotification",     (PPFN)&mpfnUsbDeregisterNotification))      == NO_ERROR
    6262               )
    6363            {
    64                 rc = mpfnUsbRegisterChangeNotification (&mNotifyId, mhev, mhev);
     64                rc = mpfnUsbRegisterChangeNotification(&mNotifyId, mhev, mhev);
    6565                if (!rc)
    6666                {
     
    7777                }
    7878
    79                 LogRel (("USBProxyServiceOs2: failed to register change notification, rc=%d\n", rc));
     79                LogRel(("USBProxyServiceOs2: failed to register change notification, rc=%d\n", rc));
    8080            }
    8181            else
    82                 LogRel (("USBProxyServiceOs2: failed to load usbcalls\n"));
    83 
    84             DosFreeModule (mhmod);
     82                LogRel(("USBProxyServiceOs2: failed to load usbcalls\n"));
     83
     84            DosFreeModule(mhmod);
    8585        }
    8686        else
    87             LogRel (("USBProxyServiceOs2: failed to load usbcalls, rc=%d\n", rc));
     87            LogRel(("USBProxyServiceOs2: failed to load usbcalls, rc=%d\n", rc));
    8888        mhmod = NULLHANDLE;
    8989    }
     
    115115    {
    116116        if (mpfnUsbDeregisterNotification)
    117             mpfnUsbDeregisterNotification (mNotifyId);
     117            mpfnUsbDeregisterNotification(mNotifyId);
    118118
    119119        mpfnUsbRegisterChangeNotification = NULL;
     
    122122        mpfnUsbQueryDeviceReport = NULL;
    123123
    124         DosFreeModule (mhmod);
     124        DosFreeModule(mhmod);
    125125        mhmod = NULLHANDLE;
    126126    }
     
    128128
    129129
    130 int USBProxyServiceOs2::captureDevice (HostUSBDevice *aDevice)
    131 {
    132     Log (("USBProxyServiceOs2::captureDevice: %p\n", aDevice));
     130int USBProxyServiceOs2::captureDevice(HostUSBDevice *aDevice)
     131{
    133132    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
    134     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     133    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     134
     135    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     136    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    135137
    136138    /*
     
    138140     */
    139141    Assert(aDevice->isStatePending());
     142    devLock.release();
    140143    interruptWait();
    141144
     
    144147
    145148
    146 int USBProxyServiceOs2::releaseDevice (HostUSBDevice *aDevice)
    147 {
    148     Log (("USBProxyServiceOs2::releaseDevice: %p\n", aDevice));
     149int USBProxyServiceOs2::releaseDevice(HostUSBDevice *aDevice)
     150{
    149151    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
    150     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     152    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     153
     154    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     155    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    151156
    152157    /*
     
    154159     */
    155160    Assert(aDevice->isStatePending());
     161    devLock.release();
    156162    interruptWait();
    157163
     
    162168bool USBProxyServiceOs2::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    163169{
     170    AssertReturn(aDevice, false);
     171    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    164172    return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
    165173}
     
    174182
    175183
    176 int USBProxyServiceOs2::interruptWait (void)
    177 {
    178     int rc = DosPostEventSem (mhev);
     184int USBProxyServiceOs2::interruptWait(void)
     185{
     186    int rc = DosPostEventSem(mhev);
    179187    return rc == NO_ERROR || rc == ERROR_ALREADY_POSTED
    180188         ? VINF_SUCCESS
    181          : RTErrConvertFromOS2 (rc);
     189         : RTErrConvertFromOS2(rc);
    182190}
    183191
    184192#include <stdio.h>
    185193
    186 PUSBDEVICE USBProxyServiceOs2::getDevices (void)
     194PUSBDEVICE USBProxyServiceOs2::getDevices(void)
    187195{
    188196    /*
     
    190198     */
    191199    ULONG cDevices = 0;
    192     int rc = mpfnUsbQueryNumberDevices ((PULONG)&cDevices); /* Thanks to com/xpcom, PULONG and ULONG * aren't the same. */
     200    int rc = mpfnUsbQueryNumberDevices((PULONG)&cDevices); /* Thanks to com/xpcom, PULONG and ULONG * aren't the same. */
    193201    if (rc)
    194202        return NULL;
  • trunk/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp

    r38016 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5454 * Initialize data members.
    5555 */
    56 USBProxyServiceSolaris::USBProxyServiceSolaris (Host *aHost)
    57     : USBProxyService (aHost), mUSBLibInitialized(false)
     56USBProxyServiceSolaris::USBProxyServiceSolaris(Host *aHost)
     57    : USBProxyService(aHost), mUSBLibInitialized(false)
    5858{
    5959    LogFlowThisFunc(("aHost=%p\n", aHost));
     
    337337     */
    338338    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
     339    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     340
     341    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    339342    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    340     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     343
    341344    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
    342345    AssertReturn(aDevice->mUsb, VERR_INVALID_POINTER);
     
    372375void USBProxyServiceSolaris::captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
    373376{
     377    AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
    374378    /*
    375379     * Remove the one-shot filter if necessary.
     
    388392     */
    389393    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
     394    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     395
     396    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    390397    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
    391     AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     398
    392399    Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
    393400    AssertReturn(aDevice->mUsb, VERR_INVALID_POINTER);
     
    423430void USBProxyServiceSolaris::releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
    424431{
     432    AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
    425433    /*
    426434     * Remove the one-shot filter if necessary.
     
    435443bool USBProxyServiceSolaris::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    436444{
     445    AssertReturn(aDevice, false);
     446    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false)
    437447    return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
    438448}
  • trunk/src/VBox/Main/src-server/win/USBProxyServiceWindows.cpp

    r37599 r41528  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2005-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    138138{
    139139    /*
     140     * Check preconditions.
     141     */
     142    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
     143    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     144
     145    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     146    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
     147
     148    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
     149
     150    /*
    140151     * Create a one-shot ignore filter for the device
    141152     * and trigger a re-enumeration of it.
     
    169180{
    170181    /*
     182     * Check preconditions.
     183     */
     184    AssertReturn(aDevice, VERR_GENERAL_FAILURE);
     185    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
     186
     187    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
     188    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
     189
     190    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
     191
     192    /*
    171193     * Create a one-shot ignore filter for the device
    172194     * and trigger a re-enumeration of it.
     
    200222bool USBProxyServiceWindows::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
    201223{
     224    AssertReturn(aDevice, false);
     225    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    202226    /* Nothing special here so far, so fall back on parent */
    203227    return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
     
    205229/// @todo remove?
    206230#if 0
    207     AssertReturn(aDevice, false);
    208     AssertReturn(aDevice->isWriteLockOnCurrentThread(), false);
    209231
    210232    /*
  • trunk/src/VBox/Main/testcase/Makefile.kmk

    r41477 r41528  
    55
    66#
    7 # Copyright (C) 2006-2012 Oracle Corporation
     7# Copyright (C) 2004-2012 Oracle Corporation
    88#
    99# This file is part of VirtualBox Open Source Edition (OSE), as
     
    184184        $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h
    185185tstUSBProxyLinux_LIBS     += \
    186         $(PATH_OUT)/lib/USBLib.a
     186        $(PATH_OUT)/lib/USBLib.a \
     187        $(PATH_OUT)/lib/VBoxCOM.a
    187188
    188189
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