VirtualBox

Changeset 40257 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Feb 27, 2012 9:25:12 AM (13 years ago)
Author:
vboxsync
Message:

Main/Medium: rework locking scheme to solve lock order violations and long GUI start up time caused by too much locking
Main/all: Remove the enter and leave methods from write locks, they cause hard to find locking problems. Better solve them explicitly.

Location:
trunk/src/VBox/Main/src-client
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r40084 r40257  
    20772077        return ptrVM.rc();
    20782078
    2079     /* leave the lock before a VMR3* call (EMT will call us back)! */
    2080     alock.leave();
     2079    /* release the lock before a VMR3* call (EMT will call us back)! */
     2080    alock.release();
    20812081
    20822082    int vrc = VMR3Reset(ptrVM);
     
    22902290                          this, pVM, aCpu);
    22912291
    2292     /* leave the lock before a VMR3* call (EMT will call us back)! */
     2292    /* release the lock before a VMR3* call (EMT will call us back)! */
    22932293    alock.release();
    22942294
     
    23542354    LogFlowThisFunc(("Sending PAUSE request...\n"));
    23552355
    2356     /* leave the lock before a VMR3* call (EMT will call us back)! */
    2357     alock.leave();
     2356    /* release the lock before a VMR3* call (EMT will call us back)! */
     2357    alock.release();
    23582358
    23592359    int vrc = VMR3Suspend(ptrVM);
     
    23892389    LogFlowThisFunc(("Sending RESUME request...\n"));
    23902390
    2391     /* leave the lock before a VMR3* call (EMT will call us back)! */
    2392     alock.leave();
     2391    /* release the lock before a VMR3* call (EMT will call us back)! */
     2392    alock.release();
    23932393
    23942394#ifdef VBOX_WITH_EXTPACK
     
    24342434    if (!ptrVM.isOk())
    24352435        return ptrVM.rc();
    2436 /** @todo leave the console lock? */
     2436
     2437/** @todo release the console lock? */
    24372438
    24382439    /* get the acpi device interface and press the button. */
     
    24812482    if (!ptrVM.isOk())
    24822483        return ptrVM.rc();
    2483 /** @todo leave the console lock? */
     2484
     2485/** @todo release the console lock? */
    24842486
    24852487    /* get the acpi device interface and check if the button press was handled. */
     
    25362538        return ptrVM.rc();
    25372539
    2538 /** @todo leave the console lock? */
     2540/** @todo release the console lock? */
    25392541
    25402542    /* get the acpi device interface and query the information. */
     
    25772579        return ptrVM.rc();
    25782580
    2579 /** @todo leave the console lock? */
     2581/** @todo release the console lock? */
    25802582
    25812583    /* get the acpi device interface and press the sleep button. */
     
    26792681        /*
    26802682         * If we fail here it means a PowerDown() call happened on another
    2681          * thread while we were doing Pause() (which leaves the Console lock).
     2683         * thread while we were doing Pause() (which releases the Console lock).
    26822684         * We assign PowerDown() a higher precedence than SaveState(),
    26832685         * therefore just return the error to the caller.
     
    28872889            tr("The virtual machine does not have a USB controller"));
    28882890
    2889     /* leave the lock because the USB Proxy service may call us back
     2891    /* release the lock because the USB Proxy service may call us back
    28902892     * (via onUSBDeviceAttach()) */
    2891     alock.leave();
     2893    alock.release();
    28922894
    28932895    /* Request the device capture */
     
    29322934     * Inform the USB device and USB proxy about what's cooking.
    29332935     */
    2934     alock.leave();
     2936    alock.release();
    29352937    HRESULT rc2 = mControl->DetachUSBDevice(aId, false /* aDone */);
    29362938    if (FAILED(rc2))
    29372939        return rc2;
    2938     alock.enter();
     2940    alock.acquire();
    29392941
    29402942    /* Request the PDM to detach the USB device. */
     
    29432945    if (SUCCEEDED(rc))
    29442946    {
    2945         /* leave the lock since we don't need it any more (note though that
     2947        /* release the lock since we don't need it any more (note though that
    29462948         * the USB Proxy service must not call us back here) */
    2947         alock.leave();
     2949        alock.release();
    29482950
    29492951        /* Request the device release. Even if it fails, the device will
     
    32693271        /*
    32703272         * If we fail here it means a PowerDown() call happened on another
    3271          * thread while we were doing Pause() (which leaves the Console lock).
     3273         * thread while we were doing Pause() (which releases the Console lock).
    32723274         * We assign PowerDown() a higher precedence than TakeSnapshot(),
    32733275         * therefore just return the error to the caller.
     
    35953597                          fForce);
    35963598
    3597     /* leave the lock before waiting for a result (EMT will call us back!) */
    3598     alock.leave();
     3599    /* release the lock before waiting for a result (EMT will call us back!) */
     3600    alock.release();
    35993601
    36003602    if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
     
    38483850                          aMediumAttachment);
    38493851
    3850     /* leave the lock before waiting for a result (EMT will call us back!) */
    3851     alock.leave();
     3852    /* release the lock before waiting for a result (EMT will call us back!) */
     3853    alock.release();
    38523854
    38533855    if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
     
    40894091                          aMediumAttachment);
    40904092
    4091     /* leave the lock before waiting for a result (EMT will call us back!) */
    4092     alock.leave();
     4093    /* release the lock before waiting for a result (EMT will call us back!) */
     4094    alock.release();
    40934095
    40944096    if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
     
    44984500                          this, ptrVM.raw(), pszDevice, uInstance, uLun, aNetworkAdapter);
    44994501
    4500     /* leave the lock before waiting for a result (EMT will call us back!) */
    4501     alock.leave();
     4502    /* release the lock before waiting for a result (EMT will call us back!) */
     4503    alock.release();
    45024504
    45034505    if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
     
    48334835        {
    48344836            /* VRDP server may call this Console object back from other threads (VRDP INPUT or OUTPUT). */
    4835             alock.leave();
     4837            alock.release();
    48364838
    48374839            if (vrdpEnabled)
     
    48524854            }
    48534855
    4854             alock.enter();
     4856            alock.acquire();
    48554857        }
    48564858    }
     
    66886690    /* ----------------------------------------------------------------------
    66896691     * DONE with necessary state changes, perform the power down actions (it's
    6690      * safe to leave the object lock now if needed)
     6692     * safe to release the object lock now if needed)
    66916693     * ---------------------------------------------------------------------- */
    66926694
     
    66996701        /* Leave the lock since EMT will call us back as addVMCaller()
    67006702         * in updateDisplayData(). */
    6701         alock.leave();
     6703        alock.release();
    67026704
    67036705        mConsoleVRDPServer->Stop();
    67046706
    6705         alock.enter();
     6707        alock.acquire();
    67066708    }
    67076709
     
    67296731                          mVMCallers));
    67306732
    6731         alock.leave();
     6733        alock.release();
    67326734
    67336735        RTSemEventWait(mVMZeroCallersSem, RT_INDEFINITE_WAIT);
    67346736
    6735         alock.enter();
     6737        alock.acquire();
    67366738    }
    67376739
     
    67536755    {
    67546756        LogFlowThisFunc(("Powering off the VM...\n"));
    6755         alock.leave();
     6757        alock.release();
    67566758        vrc = VMR3PowerOff(VMR3GetVM(pUVM));
    67576759#ifdef VBOX_WITH_EXTPACK
    67586760        mptrExtPackManager->callAllVmPowerOffHooks(this, VMR3GetVM(pUVM));
    67596761#endif
    6760         alock.enter();
     6762        alock.acquire();
    67616763    }
    67626764
     
    67726774
    67736775        /* Leave the lock since EMT will call us back as addVMCaller() */
    6774         alock.leave();
     6776        alock.release();
    67756777
    67766778        m_pVMMDev->hgcmShutdown();
    67776779
    6778         alock.enter();
     6780        alock.acquire();
    67796781    }
    67806782
     
    68056807
    68066808        /* Now we've got to destroy the VM as well. (mpVM is not valid beyond
    6807          * this point). We leave the lock before calling VMR3Destroy() because
     6809         * this point). We release the lock before calling VMR3Destroy() because
    68086810         * it will result into calling destructors of drivers associated with
    68096811         * Console children which may in turn try to lock Console (e.g. by
     
    68186820        LogFlowThisFunc(("Destroying the VM...\n"));
    68196821
    6820         alock.leave();
     6822        alock.release();
    68216823
    68226824        vrc = VMR3Destroy(VMR3GetVM(pUVM));
    68236825
    68246826        /* take the lock again */
    6825         alock.enter();
     6827        alock.acquire();
    68266828
    68276829        /* advance percent count */
     
    69306932             * UpdateState we will require Machine and SessionMachine locks
    69316933             * (remember that here we're holding the Console lock here, and also
    6932              * all locks that have been entered by the thread before calling
     6934             * all locks that have been acquire by the thread before calling
    69336935             * this method).
    69346936             */
     
    76487650    AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    76497651
    7650     /* still want a lock object because we need to leave it */
     7652    /* still want a lock object because we need to release it */
    76517653    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    76527654
     
    76807682                      Address.c_str(), uuid.raw()));
    76817683
    7682     /* leave the lock before a VMR3* call (EMT will call us back)! */
    7683     alock.leave();
     7684    /* release the lock before a VMR3* call (EMT will call us back)! */
     7685    alock.release();
    76847686
    76857687/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
     
    76897691
    76907692    /* restore the lock */
    7691     alock.enter();
     7693    alock.acquire();
    76927694
    76937695    /* hrc is S_OK here */
     
    77907792    AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    77917793
    7792     /* still want a lock object because we need to leave it */
     7794    /* still want a lock object because we need to release it */
    77937795    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    77947796
     
    78047806                     (*aIt)->id().raw()));
    78057807
    7806     /* leave the lock before a VMR3* call (EMT will call us back)! */
    7807     alock.leave();
     7808    /* release the lock before a VMR3* call (EMT will call us back)! */
     7809    alock.release();
    78087810
    78097811/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
     
    82668268    if (RT_SUCCESS(vrc))
    82678269    {
    8268         /* leave the lock before calling Host in VBoxSVC since Host may call
     8270        /* release the lock before calling Host in VBoxSVC since Host may call
    82698271         * us back from under its lock (e.g. onUSBDeviceAttach()) which would
    82708272         * produce an inter-process dead-lock otherwise. */
    82718273        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    8272         alock.leave();
     8274        alock.release();
    82738275
    82748276        HRESULT hrc = mControl->AutoCaptureUSBDevices();
     
    83008302    mUSBDevices.clear();
    83018303
    8302     /* leave the lock before calling Host in VBoxSVC since Host may call
     8304    /* release the lock before calling Host in VBoxSVC since Host may call
    83038305     * us back from under its lock (e.g. onUSBDeviceAttach()) which would
    83048306     * produce an inter-process dead-lock otherwise. */
    83058307    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    8306     alock.leave();
     8308    alock.release();
    83078309
    83088310    mControl->DetachAllUSBDevices(aDone);
     
    85758577
    85768578        /* Does VRDP server call Console from the other thread?
    8577          * Not sure (and can change), so leave the lock just in case.
     8579         * Not sure (and can change), so release the lock just in case.
    85788580         */
    8579         alock.leave();
     8581        alock.release();
    85808582        vrc = server->Launch();
    8581         alock.enter();
     8583        alock.acquire();
    85828584
    85838585        if (vrc == VERR_NET_ADDRESS_IN_USE)
     
    86278629        PVM pVM;
    86288630        /*
    8629          * leave the lock since EMT will call Console. It's safe because
     8631         * release the lock since EMT will call Console. It's safe because
    86308632         * mMachineState is either Starting or Restoring state here.
    86318633         */
    8632         alock.leave();
     8634        alock.release();
    86338635
    86348636        vrc = VMR3Create(cCpus,
     
    86408642                         &pVM);
    86418643
    8642         alock.enter();
     8644        alock.acquire();
    86438645
    86448646        /* Enable client connections to the server. */
     
    86778679                {
    86788680                    /* Does the code below call Console from the other thread?
    8679                      * Not sure, so leave the lock just in case. */
    8680                     alock.leave();
     8681                     * Not sure, so release the lock just in case. */
     8682                    alock.release();
    86818683
    86828684                    for (SharedFolderDataMap::const_iterator it = task->mSharedFolders.begin();
     
    86988700                        rc = S_OK;          // do not fail with broken shared folders
    86998701
    8700                     /* enter the lock again */
    8701                     alock.enter();
     8702                    /* acquire the lock again */
     8703                    alock.acquire();
    87028704                }
    87038705
     
    87088710                if (FAILED(rc)) break;
    87098711
    8710                 /* leave the lock before a lengthy operation */
    8711                 alock.leave();
     8712                /* release the lock before a lengthy operation */
     8713                alock.release();
    87128714
    87138715                /* Load saved state? */
     
    88228824                }
    88238825
    8824                 /* enter the lock again */
    8825                 alock.enter();
     8826                /* acquire the lock again */
     8827                alock.acquire();
    88268828            }
    88278829            while (0);
     
    88358837                /* powerDown() will call VMR3Destroy() and do all necessary
    88368838                 * cleanup (VRDP, USB devices) */
     8839                alock.release();
    88378840                HRESULT rc2 = pConsole->powerDown();
     8841                alock.acquire();
    88388842                AssertComRC(rc2);
    88398843            }
     
    88458849                 * be sticky but our error callback isn't.
    88468850                 */
    8847                 alock.leave();
     8851                alock.release();
    88488852                VMR3AtErrorDeregister(pVM, Console::genericVMSetErrorCallback, &task->mErrorMsg);
    88498853                /** @todo register another VMSetError callback? */
    8850                 alock.enter();
     8854                alock.acquire();
    88518855            }
    88528856        }
     
    89148918     */
    89158919
    8916     /* leave the lock, don't need it any more */
    8917     alock.leave();
     8920    /* release the lock, don't need it any more */
     8921    alock.release();
    89188922
    89198923    if (SUCCEEDED(rc))
     
    91149118            pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, ptrVM.rawUVM());
    91159119
    9116             alock.leave();
     9120            alock.release();
    91179121            LogFlowFunc(("VMR3Save...\n"));
    91189122            int vrc = VMR3Save(ptrVM,
     
    91229126                               static_cast<IProgress *>(pTask->mProgress),
    91239127                               &fSuspenededBySave);
    9124             alock.enter();
     9128            alock.acquire();
    91259129            if (RT_FAILURE(vrc))
    91269130                throw setErrorStatic(E_FAIL,
     
    91909194
    91919195                /*
    9192                  * don't leave the lock since reconfigureMediumAttachment
     9196                 * don't release the lock since reconfigureMediumAttachment
    91939197                 * isn't going to need the Console lock.
    91949198                 */
     
    92659269                LogFlowFunc(("VMR3Resume...\n"));
    92669270                SafeVMPtr ptrVM(that);
    9267                 alock.leave();
     9271                alock.release();
    92689272                int vrc = VMR3Resume(ptrVM);
    9269                 alock.enter();
     9273                alock.acquire();
    92709274                if (RT_FAILURE(vrc))
    92719275                {
     
    93239327                        LogFlowFunc(("VMR3Resume (on failure)...\n"));
    93249328                        SafeVMPtr ptrVM(that);
    9325                         alock.leave();
     9329                        alock.release();
    93269330                        int vrc = VMR3Resume(ptrVM); AssertLogRelRC(vrc);
    9327                         alock.enter();
     9331                        alock.acquire();
    93289332                        if (RT_FAILURE(vrc))
    93299333                            that->setMachineState(MachineState_Paused);
     
    94119415         */
    94129416        task->releaseVMCaller();
     9417        thatLock.release();
    94139418        rc = that->powerDown();
     9419        thatLock.acquire();
    94149420    }
    94159421
     
    94589464    /* release VM caller to avoid the powerDown() deadlock */
    94599465    task->releaseVMCaller();
     9466
     9467    thatLock.release();
    94609468
    94619469    that->powerDown(task->mServerProgress);
  • trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp

    r40066 r40257  
    55
    66/*
    7  * Copyright (C) 2010 Oracle Corporation
     7 * Copyright (C) 2010-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    886886                        if (pState->mfSuspendedByUs)
    887887                        {
    888                             autoLock.leave();
     888                            autoLock.release();
    889889                            int rc = VMR3Resume(VMR3GetVM(pState->mpUVM));
    890890                            AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
    891                             autoLock.enter();
     891                            autoLock.acquire();
    892892                        }
    893893                    }
     
    901901        }
    902902    }
    903     autoLock.leave();
     903    autoLock.release();
    904904
    905905    /*
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r39603 r40257  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    20382038    if (pVM.isOk())
    20392039    {
    2040         /* Must leave the lock here because the changeFramebuffer will
     2040        /* Must release the lock here because the changeFramebuffer will
    20412041         * also obtain it. */
    2042         alock.leave ();
     2042        alock.release();
    20432043
    20442044        /* send request to the EMT thread */
     
    20462046                                   (PFNRT) changeFramebuffer, 3, this, aFramebuffer, aScreenId);
    20472047
    2048         alock.enter ();
     2048        alock.acquire();
    20492049
    20502050        ComAssertRCRet (vrc, E_FAIL);
     
    20642064                VMMDev *pVMMDev = mParent->getVMMDev();
    20652065
    2066                 alock.leave ();
     2066                alock.release();
    20672067
    20682068                if (pVMMDev)
     
    20702070                /*ComAssertRCRet (vrc, E_FAIL);*/
    20712071
    2072                 alock.enter ();
     2072                alock.acquire();
    20732073            }
    20742074        }
     
    21552155//        return setError(E_FAIL, tr("Not enough VRAM for the selected video mode"));
    21562156
    2157     /* Have to leave the lock because the pfnRequestDisplayChange
     2157    /* Have to release the lock because the pfnRequestDisplayChange
    21582158     * will call EMT.  */
    2159     alock.leave ();
     2159    alock.release();
    21602160
    21612161    VMMDev *pVMMDev = mParent->getVMMDev();
     
    21762176    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    21772177
    2178     /* Have to leave the lock because the pfnRequestSeamlessChange will call EMT.  */
    2179     alock.leave ();
     2178    /* Have to release the lock because the pfnRequestSeamlessChange will call EMT.  */
     2179    alock.release();
    21802180
    21812181    VMMDev *pVMMDev = mParent->getVMMDev();
     
    23772377    LogRelFlowFunc (("Sending SCREENSHOT request\n"));
    23782378
    2379     /* Leave lock because other thread (EMT) is called and it may initiate a resize
     2379    /* Release lock because other thread (EMT) is called and it may initiate a resize
    23802380     * which also needs lock.
    23812381     *
    23822382     * This method does not need the lock anymore.
    23832383     */
    2384     alock.leave();
     2384    alock.release();
    23852385
    23862386    int vrc = displayTakeScreenshot(pVM, this, mpDrv, aScreenId, address, width, height);
     
    24302430    LogRelFlowFunc (("Sending SCREENSHOT request\n"));
    24312431
    2432     /* Leave lock because other thread (EMT) is called and it may initiate a resize
     2432    /* Release lock because other thread (EMT) is called and it may initiate a resize
    24332433     * which also needs lock.
    24342434     *
    24352435     * This method does not need the lock anymore.
    24362436     */
    2437     alock.leave();
     2437    alock.release();
    24382438
    24392439    size_t cbData = width * 4 * height;
     
    25072507    LogRelFlowFunc (("Sending SCREENSHOT request\n"));
    25082508
    2509     /* Leave lock because other thread (EMT) is called and it may initiate a resize
     2509    /* Release lock because other thread (EMT) is called and it may initiate a resize
    25102510     * which also needs lock.
    25112511     *
    25122512     * This method does not need the lock anymore.
    25132513     */
    2514     alock.leave();
     2514    alock.release();
    25152515
    25162516    size_t cbData = width * 4 * height;
     
    26762676    if (FAILED(pVM.rc())) return pVM.rc();
    26772677
    2678     /* Leave lock because the call scheduled on EMT may also try to take it. */
    2679     alock.leave();
     2678    /* Release lock because the call scheduled on EMT may also try to take it. */
     2679    alock.release();
    26802680
    26812681    /*
     
    28002800    LogRelFlowFunc (("Sending DPYUPDATE request\n"));
    28012801
    2802     /* Have to leave the lock when calling EMT.  */
    2803     alock.leave ();
     2802    /* Have to release the lock when calling EMT.  */
     2803    alock.release();
    28042804
    28052805    /* pdm.h says that this has to be called from the EMT thread */
    28062806    int rcVBox = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)Display::InvalidateAndUpdateEMT,
    28072807                                     1, this);
    2808     alock.enter ();
     2808    alock.acquire();
    28092809
    28102810    if (RT_FAILURE(rcVBox))
     
    30033003
    30043004#if defined(VBOX_WITH_CROGL)
    3005         /* Leave the lock, because SHCRGL_HOST_FN_SCREEN_CHANGED will read current framebuffer */
     3005        /* Release the lock, because SHCRGL_HOST_FN_SCREEN_CHANGED will read current framebuffer */
    30063006        {
    30073007            BOOL is3denabled;
     
    30103010            if (is3denabled)
    30113011            {
    3012                 alock.leave ();
     3012                alock.release();
    30133013            }
    30143014        }
  • trunk/src/VBox/Main/src-client/SessionImpl.cpp

    r40177 r40257  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    936936         *  SessionState_Closing here, so it's safe.
    937937         */
    938         alock.leave();
     938        alock.release();
    939939
    940940        LogFlowThisFunc(("Calling mControl->OnSessionEnd()...\n"));
     
    942942        LogFlowThisFunc(("mControl->OnSessionEnd()=%08X\n", rc));
    943943
    944         alock.enter();
     944        alock.acquire();
    945945
    946946        /*
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