VirtualBox

Changeset 31019 in vbox


Ignore:
Timestamp:
Jul 22, 2010 5:48:18 PM (15 years ago)
Author:
vboxsync
Message:

Main: rename LockForSession() API to LockMachine() and fix parameters; move code from internal open*Session() methods into LockMachine()

Location:
trunk/src/VBox
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp

    r31016 r31019  
    824824
    825825        // open a session
    826         SessionType_T st;
    827         CHECK_ERROR_BREAK(m, LockForSession(session, false /* fPermitShared */, &st));
     826        CHECK_ERROR_BREAK(m, LockMachine(session, LockType_Write));
    828827        fSessionOpened = true;
    829828
  • trunk/src/VBox/Frontends/VBoxHeadless/testcase/tstHeadless.cpp

    r31016 r31019  
    150150        {
    151151            RTPrintf ("Opening an existing session...\n");
    152             SessionType_T st;
    153             CHECK_ERROR_BREAK(m, LockForSession(session, true /* fPermitShared */, &st));
     152            CHECK_ERROR_BREAK(m, LockMachine(session, LockType_Shared));
    154153
    155154            ComPtr <IConsole> console;
  • trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp

    r31016 r31019  
    18641864        CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[0]), ptrMachine.asOutParam()), 1);
    18651865
    1866     SessionType_T st;
    1867     CHECK_ERROR_RET(ptrMachine, LockForSession(aSession, true /* fPermitShared */, &st), 1);
     1866    CHECK_ERROR_RET(ptrMachine, LockMachine(aSession, LockType_Shared), 1);
    18681867
    18691868    /*
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp

    r31016 r31019  
    8888
    8989    /* open a session for the VM */
    90     SessionType_T st;
    91     CHECK_ERROR_RET(machine, LockForSession(a->session, true /* fPermitShared */, &st), 1);
     90    CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    9291
    9392    do
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r31016 r31019  
    286286        {
    287287            /* open an existing session for VM */
    288             SessionType_T st;
    289             CHECK_ERROR_BREAK(machine, LockForSession(a->session, true /* fPermitShared */, &st));
     288            CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Shared));
    290289            // @todo r=dj assert that it's an existing session
    291290
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp

    r31016 r31019  
    8888    {
    8989        /* open a session for the VM - new or existing */
    90         SessionType_T st;
    91         CHECK_ERROR_RET(machine, LockForSession(a->session, true /* fPermitShared */, &st), 1);
     90        CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    9291
    9392        /* get the mutable session machine */
     
    154153    {
    155154        /* open a session for the VM - new or existing */
    156         SessionType_T st;
    157         CHECK_ERROR_RET(machine, LockForSession(a->session, true /* fPermitShared */, &st), 1);
     155        CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
    158156
    159157        /* get the mutable session machine */
     
    215213    {
    216214        /* open a session for the VM - new or existing */
    217         SessionType_T st;
    218         CHECK_ERROR_RET(machine, LockForSession(a->session, true /* fPermitShared */, &st), 1);
     215        CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    219216
    220217        /* get the mutable session machine */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r31016 r31019  
    21352135
    21362136        /* open an existing session for the VM */
    2137         SessionType_T st;
    2138         rc = machine->LockForSession(a->session, true /* fPermitShared */, &st);
     2137        rc = machine->LockMachine(a->session, LockType_Shared);
    21392138        if (SUCCEEDED(rc))
    21402139            /* get the session machine */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r31016 r31019  
    418418        {
    419419            /* we have to open a session for this task */
    420             SessionType_T st;
    421             CHECK_ERROR_BREAK(machine, LockForSession(a->session, false /* fPermitShared */, &st));
     420            CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Write));
    422421            do
    423422            {
     
    453452        {
    454453            /* we have to open a session for this task */
    455             SessionType_T st;
    456             CHECK_ERROR_BREAK(machine, LockForSession(a->session, false /* fPermitShared */, &st));
     454            CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Write));
    457455            do
    458456            {
     
    728726
    729727            /* open an existing session for the VM */
    730             SessionType_T st;
    731             CHECK_ERROR_RET(machine, LockForSession(a->session, true /* fPermitShared */, &st), 1);
     728            CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    732729            /* get the session machine */
    733730            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
     
    744741            /* open a session for the VM */
    745742            SessionType_T st;
    746             CHECK_ERROR_RET(machine, LockForSession(a->session, false /* fPermitShared */, &st), 1);
     743            CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
    747744
    748745            /* get the mutable session machine */
     
    794791
    795792            /* open an existing session for the VM */
    796             SessionType_T st;
    797             CHECK_ERROR_RET(machine, LockForSession(a->session, true /* fPermitShared */, &st), 1);
     793            CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    798794            /* get the session machine */
    799795            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
     
    809805        {
    810806            /* open a session for the VM */
    811             SessionType_T st;
    812             CHECK_ERROR_RET(machine, LockForSession(a->session, false /* fPermitShared */, &st), 1);
     807            CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
    813808
    814809            /* get the mutable session machine */
     
    880875
    881876    /* open an existing session for the VM. */
    882     SessionType_T st;
    883     CHECK_ERROR(machine, LockForSession(a->session, true /* fPermitShared */, &st));
     877    CHECK_ERROR(machine, LockMachine(a->session, LockType_Shared));
    884878    if (SUCCEEDED(rc))
    885879    {
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp

    r31016 r31019  
    312312
    313313    /* open a session for the VM */
    314     SessionType_T st;
    315     CHECK_ERROR_RET(machine, LockForSession(a->session, false /* fPermitShared */, &st), 1);
     314    CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
    316315
    317316    /* get the mutable session machine */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp

    r31016 r31019  
    240240    {
    241241        /* we have to open a session for this task (new or shared) */
    242         SessionType_T st;
    243         rc = pMachine->LockForSession(a->session, true /* fPermitShared */, &st);
     242        rc = pMachine->LockMachine(a->session, LockType_Shared);
    244243        ComPtr<IConsole> console;
    245244        CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp

    r31016 r31019  
    173173
    174174    /* open a session for the VM (new or shared) */
    175     SessionType_T type;
    176     rc = machine->LockForSession(a->session, true /* fPermitShared */, &type);
    177     bool fRunTime = (type == SessionType_Shared);
     175    CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
     176    SessionType_T st;
     177    CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), 1);
     178    bool fRunTime = (st == SessionType_Shared);
     179
    178180    if (fRunTime && !RTStrICmp(pszType, "hdd"))
    179181    {
     
    755757
    756758    /* open a session for the VM */
    757     SessionType_T st;
    758     CHECK_ERROR_RET(machine, LockForSession(a->session, false /* fPermitShared */, &st), 1);
     759    CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
    759760
    760761    /* get the mutable session machine */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp

    r31016 r31019  
    417417    {
    418418        /* open a session for the VM */
    419         SessionType_T st;
    420         CHECK_ERROR_RET(cmd.mMachine, LockForSession(a->session, false /* fPermitShared */, &st), 1);
     419        CHECK_ERROR_RET(cmd.mMachine, LockMachine(a->session, LockType_Write), 1);
    421420        /* get the mutable session machine */
    422421        a->session->COMGETTER(Machine)(cmd.mMachine.asOutParam());
  • trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp

    r31016 r31019  
    13651365    AssertReleaseRC(vrc);
    13661366
    1367     SessionType_T st;
    1368     rc = pMachine->LockForSession(session, false /* fPermitShared */, &st);
     1367    rc = pMachine->LockMachine(session, LockType_Write);
    13691368    if (FAILED(rc))
    13701369    {
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp

    r31008 r31019  
    21792179    if (!foundMachine.isNull())
    21802180    {
    2181         KSessionType t = foundMachine.LockForSession(session, aExisting /* fPermitShared */);
    2182         if (t == KSessionType_Shared)
     2181        foundMachine.LockMachine(session,
     2182                                 (aExisting) ? KLockType_Shared : KLockType_Write);
     2183        if (session.GetType() == KSessionType_Shared)
    21832184        {
    21842185            CMachine machine = session.GetMachine();
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMPreviewWindow.cpp

    r31008 r31019  
    245245                {
    246246                    CVirtualBox vbox = vboxGlobal().virtualBox();
    247                     m_machine.LockForSession(session, true /* fPermitShared */);
     247                    m_machine.LockMachine(session, KLockType_Shared);
    248248                    if (vbox.isOk())
    249249                    {
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp

    r31008 r31019  
    797797    CMachine foundMachine = vbox.GetMachine(id);
    798798    if (!foundMachine.isNull())
    799         foundMachine.LockForSession(session, false /* fPermitShared */);
     799        foundMachine.LockMachine(session, KLockType_Write);
    800800    if (!vbox.isOk())
    801801    {
  • trunk/src/VBox/Main/ApplianceImplImport.cpp

    r31008 r31019  
    12331233        {
    12341234            const MyHardDiskAttachment &mhda = *itM;
    1235             rc2 = mhda.pMachine->LockForSession(stack.pSession, false /* fPermitShared */, NULL);
     1235            rc2 = mhda.pMachine->LockMachine(stack.pSession, LockType_Write);
    12361236            if (SUCCEEDED(rc2))
    12371237            {
     
    17601760        {
    17611761            // to attach things we need to open a session for the new machine
    1762             rc = pNewMachine->LockForSession(stack.pSession, false /* fPermitShared */, NULL);
     1762            rc = pNewMachine->LockMachine(stack.pSession, LockType_Write);
    17631763            if (FAILED(rc)) DebugBreakThrow(rc);
    17641764            stack.fSessionOpen = true;
     
    18721872        {
    18731873            // to attach things we need to open a session for the new machine
    1874             rc = pNewMachine->LockForSession(stack.pSession, false /* fPermitShared */, NULL);
     1874            rc = pNewMachine->LockMachine(stack.pSession, LockType_Write);
    18751875            if (FAILED(rc)) DebugBreakThrow(rc);
    18761876            stack.fSessionOpen = true;
  • trunk/src/VBox/Main/MachineImpl.cpp

    r31008 r31019  
    26812681 *  @note Locks objects!
    26822682 */
    2683 STDMETHODIMP Machine::LockForSession(ISession *aSession,
    2684                                      BOOL fPermitShared,
    2685                                      SessionType_T *pSessionType)
     2683STDMETHODIMP Machine::LockMachine(ISession *aSession,
     2684                                  LockType_T lockType)
    26862685{
    26872686    CheckComArgNotNull(aSession);
     
    27002699
    27012700    /* get the IInternalSessionControl interface */
    2702     ComPtr<IInternalSessionControl> control = aSession;
    2703     ComAssertMsgRet(!!control, ("No IInternalSessionControl interface"),
     2701    ComPtr<IInternalSessionControl> pSessionControl = aSession;
     2702    ComAssertMsgRet(!!pSessionControl, ("No IInternalSessionControl interface"),
    27042703                    E_INVALIDARG);
    27052704
    2706     rc = openSession(control);
    2707 
    2708     if (FAILED(rc) && fPermitShared)
    2709         // try again @todo r=dj check exact error code!
    2710         rc = openExistingSession(control);
     2705    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     2706
     2707    if (!mData->mRegistered)
     2708        return setError(E_UNEXPECTED,
     2709                        tr("The machine '%ls' is not registered"),
     2710                        mUserData->mName.raw());
     2711
     2712    LogFlowThisFunc(("mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
     2713
     2714    /* Hack: in case the session is closing and there is a progress object
     2715     * which allows waiting for the session to be closed, take the opportunity
     2716     * and do a limited wait (max. 1 second). This helps a lot when the system
     2717     * is busy and thus session closing can take a little while. */
     2718    if (    mData->mSession.mState == SessionState_Unlocking
     2719        &&  mData->mSession.mProgress)
     2720    {
     2721        alock.release();
     2722        mData->mSession.mProgress->WaitForCompletion(1000);
     2723        alock.acquire();
     2724        LogFlowThisFunc(("after waiting: mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
     2725    }
     2726
     2727    // try again now
     2728    if (    mData->mSession.mState == SessionState_Locked
     2729         || mData->mSession.mState == SessionState_Unlocking
     2730       )
     2731    {
     2732        // If the machine is write-locked already (i.e. SessionMachine exists) and
     2733        // caller permits sharing, then try to do that now
     2734        if (    (mData->mSession.mState == SessionState_Locked)
     2735             && (lockType == LockType_Shared)
     2736           )
     2737        {
     2738            ComAssertRet(!mData->mSession.mDirectControl.isNull(), E_FAIL);
     2739
     2740            // copy member variables before leaving lock
     2741            ComPtr<IInternalSessionControl> pDirectControl = mData->mSession.mDirectControl;
     2742            ComObjPtr<SessionMachine> pSessionMachine = mData->mSession.mMachine;
     2743            AssertReturn(!pSessionMachine.isNull(), E_FAIL);
     2744
     2745            /*
     2746             *  Leave the lock before calling the client process. It's safe here
     2747             *  since the only thing to do after we get the lock again is to add
     2748             *  the remote control to the list (which doesn't directly influence
     2749             *  anything).
     2750             */
     2751            alock.leave();
     2752
     2753            // get the console from the direct session (this is a remote call)
     2754            ComPtr<IConsole> pConsole;
     2755            LogFlowThisFunc(("Calling GetRemoteConsole()...\n"));
     2756            rc = pDirectControl->GetRemoteConsole(pConsole.asOutParam());
     2757            LogFlowThisFunc(("GetRemoteConsole() returned %08X\n", rc));
     2758            if (FAILED(rc))
     2759                /* The failure may occur w/o any error info (from RPC), so provide one */
     2760                return setError(VBOX_E_VM_ERROR,
     2761                                tr("Failed to get a console object from the direct session (%Rrc)"), rc);
     2762
     2763            ComAssertRet(!pConsole.isNull(), E_FAIL);
     2764
     2765            /* attach the remote session to the machine */
     2766            LogFlowThisFunc(("Calling AssignRemoteMachine()...\n"));
     2767            rc = pSessionControl->AssignRemoteMachine(pSessionMachine, pConsole);
     2768            LogFlowThisFunc(("AssignRemoteMachine() returned %08X\n", rc));
     2769
     2770            /* The failure may occur w/o any error info (from RPC), so provide one */
     2771            if (FAILED(rc))
     2772                return setError(VBOX_E_VM_ERROR,
     2773                                tr("Failed to assign the machine to the session (%Rrc)"),
     2774                                rc);
     2775            alock.enter();
     2776
     2777            /* need to revalidate the state after entering the lock again */
     2778            if (mData->mSession.mState != SessionState_Locked)
     2779            {
     2780                pSessionControl->Uninitialize();
     2781                return setError(VBOX_E_INVALID_SESSION_STATE,
     2782                                tr("The machine '%ls' was unlocked unexpectedly while attempting to share its session"),
     2783                                mUserData->mName.raw());
     2784            }
     2785
     2786            // add the caller's control to the list
     2787            mData->mSession.mRemoteControls.push_back(pSessionControl);
     2788        }
     2789        else
     2790            // still unlocking, or caller has not permitted sharing:
     2791            return setError(VBOX_E_INVALID_OBJECT_STATE,
     2792                            tr("The machine '%ls' is already locked for a session (or being unlocked)"),
     2793                            mUserData->mName.raw());
     2794    }
     2795    else
     2796    {
     2797        // no lock exists or sharing not permitted: then create the session machine
     2798
     2799        /* may not be busy */
     2800        AssertReturn(!Global::IsOnlineOrTransient(mData->mMachineState), E_FAIL);
     2801
     2802        // get the caller's session PID
     2803        RTPROCESS pid = NIL_RTPROCESS;
     2804        AssertCompile(sizeof(ULONG) == sizeof(RTPROCESS));
     2805        pSessionControl->GetPID((ULONG*)&pid);
     2806        Assert(pid != NIL_RTPROCESS);
     2807
     2808        if (mData->mSession.mState == SessionState_Spawning)
     2809        {
     2810            /* This machine is awaiting for a spawning session to be opened, so
     2811             * reject any other open attempts from processes other than one
     2812             * started by #openRemoteSession(). */
     2813
     2814            LogFlowThisFunc(("mSession.mPid=%d(0x%x)\n", mData->mSession.mPid, mData->mSession.mPid));
     2815            LogFlowThisFunc(("session.pid=%d(0x%x)\n", pid, pid));
     2816
     2817            if (mData->mSession.mPid != pid)
     2818                return setError(E_ACCESSDENIED,
     2819                                tr("An unexpected process (PID=0x%08X) has tried to lock the "
     2820                                   "machine '%ls', while only the process started by launchVMProcess (PID=0x%08X) is allowed"),
     2821                                pid, mUserData->mName.raw(), mData->mSession.mPid);
     2822        }
     2823
     2824        // create the mutable SessionMachine from the current machine
     2825        ComObjPtr<SessionMachine> sessionMachine;
     2826        sessionMachine.createObject();
     2827        rc = sessionMachine->init(this);
     2828        AssertComRC(rc);
     2829
     2830        /* NOTE: doing return from this function after this point but
     2831         * before the end is forbidden since it may call SessionMachine::uninit()
     2832         * (through the ComObjPtr's destructor) which requests the VirtualBox write
     2833         * lock while still holding the Machine lock in alock so that a deadlock
     2834         * is possible due to the wrong lock order. */
     2835
     2836        if (SUCCEEDED(rc))
     2837        {
     2838            /*
     2839             *  Set the session state to Spawning to protect against subsequent
     2840             *  attempts to open a session and to unregister the machine after
     2841             *  we leave the lock.
     2842             */
     2843            SessionState_T origState = mData->mSession.mState;
     2844            mData->mSession.mState = SessionState_Spawning;
     2845
     2846            /*
     2847             *  Leave the lock before calling the client process -- it will call
     2848             *  Machine/SessionMachine methods. Leaving the lock here is quite safe
     2849             *  because the state is Spawning, so that openRemotesession() and
     2850             *  openExistingSession() calls will fail. This method, called before we
     2851             *  enter the lock again, will fail because of the wrong PID.
     2852             *
     2853             *  Note that mData->mSession.mRemoteControls accessed outside
     2854             *  the lock may not be modified when state is Spawning, so it's safe.
     2855             */
     2856            alock.leave();
     2857
     2858            LogFlowThisFunc(("Calling AssignMachine()...\n"));
     2859            rc = pSessionControl->AssignMachine(sessionMachine);
     2860            LogFlowThisFunc(("AssignMachine() returned %08X\n", rc));
     2861
     2862            /* The failure may occur w/o any error info (from RPC), so provide one */
     2863            if (FAILED(rc))
     2864                setError(VBOX_E_VM_ERROR,
     2865                         tr("Failed to assign the machine to the session (%Rrc)"), rc);
     2866
     2867            if (    SUCCEEDED(rc)
     2868                 && origState == SessionState_Spawning
     2869               )
     2870            {
     2871                /* complete the remote session initialization */
     2872
     2873                /* get the console from the direct session */
     2874                ComPtr<IConsole> console;
     2875                rc = pSessionControl->GetRemoteConsole(console.asOutParam());
     2876                ComAssertComRC(rc);
     2877
     2878                if (SUCCEEDED(rc) && !console)
     2879                {
     2880                    ComAssert(!!console);
     2881                    rc = E_FAIL;
     2882                }
     2883
     2884                /* assign machine & console to the remote session */
     2885                if (SUCCEEDED(rc))
     2886                {
     2887                    /*
     2888                     *  after openRemoteSession(), the first and the only
     2889                     *  entry in remoteControls is that remote session
     2890                     */
     2891                    LogFlowThisFunc(("Calling AssignRemoteMachine()...\n"));
     2892                    rc = mData->mSession.mRemoteControls.front()->AssignRemoteMachine(sessionMachine, console);
     2893                    LogFlowThisFunc(("AssignRemoteMachine() returned %08X\n", rc));
     2894
     2895                    /* The failure may occur w/o any error info (from RPC), so provide one */
     2896                    if (FAILED(rc))
     2897                        setError(VBOX_E_VM_ERROR,
     2898                                 tr("Failed to assign the machine to the remote session (%Rrc)"), rc);
     2899                }
     2900
     2901                if (FAILED(rc))
     2902                    pSessionControl->Uninitialize();
     2903            }
     2904
     2905            /* enter the lock again */
     2906            alock.enter();
     2907
     2908            /* Restore the session state */
     2909            mData->mSession.mState = origState;
     2910        }
     2911
     2912        /* finalize spawning anyway (this is why we don't return on errors above) */
     2913        if (mData->mSession.mState == SessionState_Spawning)
     2914        {
     2915            /* Note that the progress object is finalized later */
     2916            /** @todo Consider checking mData->mSession.mProgress for cancellation
     2917             *        around here.  */
     2918
     2919            /* We don't reset mSession.mPid here because it is necessary for
     2920             * SessionMachine::uninit() to reap the child process later. */
     2921
     2922            if (FAILED(rc))
     2923            {
     2924                /* Close the remote session, remove the remote control from the list
     2925                 * and reset session state to Closed (@note keep the code in sync
     2926                 * with the relevant part in openSession()). */
     2927
     2928                Assert(mData->mSession.mRemoteControls.size() == 1);
     2929                if (mData->mSession.mRemoteControls.size() == 1)
     2930                {
     2931                    ErrorInfoKeeper eik;
     2932                    mData->mSession.mRemoteControls.front()->Uninitialize();
     2933                }
     2934
     2935                mData->mSession.mRemoteControls.clear();
     2936                mData->mSession.mState = SessionState_Unlocked;
     2937            }
     2938        }
     2939        else
     2940        {
     2941            /* memorize PID of the directly opened session */
     2942            if (SUCCEEDED(rc))
     2943                mData->mSession.mPid = pid;
     2944        }
     2945
     2946        if (SUCCEEDED(rc))
     2947        {
     2948            /* memorize the direct session control and cache IUnknown for it */
     2949            mData->mSession.mDirectControl = pSessionControl;
     2950            mData->mSession.mState = SessionState_Locked;
     2951            /* associate the SessionMachine with this Machine */
     2952            mData->mSession.mMachine = sessionMachine;
     2953
     2954            /* request an IUnknown pointer early from the remote party for later
     2955             * identity checks (it will be internally cached within mDirectControl
     2956             * at least on XPCOM) */
     2957            ComPtr<IUnknown> unk = mData->mSession.mDirectControl;
     2958            NOREF(unk);
     2959        }
     2960
     2961        /* Leave the lock since SessionMachine::uninit() locks VirtualBox which
     2962         * would break the lock order */
     2963        alock.leave();
     2964
     2965        /* uninitialize the created session machine on failure */
     2966        if (FAILED(rc))
     2967            sessionMachine->uninit();
     2968
     2969    }
    27112970
    27122971    if (SUCCEEDED(rc))
     
    27202979        /* fire an event */
    27212980        mParent->onSessionStateChange(getId(), SessionState_Locked);
    2722 
    2723         // return session type to caller
    2724         if (pSessionType)
    2725             aSession->COMGETTER(Type)(pSessionType);
    27262981    }
    27272982
     
    53545609
    53555610/**
    5356  *  @note Locks this object for writing, calls the client process (outside the
    5357  *        lock).
    5358  */
    5359 HRESULT Machine::openSession(IInternalSessionControl *aControl)
    5360 {
    5361     LogFlowThisFuncEnter();
    5362 
    5363     AssertReturn(aControl, E_FAIL);
    5364 
    5365     AutoCaller autoCaller(this);
    5366     if (FAILED(autoCaller.rc()))
    5367         return autoCaller.rc();
    5368 
    5369     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    5370 
    5371     if (!mData->mRegistered)
    5372         return setError(E_UNEXPECTED,
    5373                         tr("The machine '%ls' is not registered"),
    5374                         mUserData->mName.raw());
    5375 
    5376     LogFlowThisFunc(("mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
    5377 
    5378     /* Hack: in case the session is closing and there is a progress object
    5379      * which allows waiting for the session to be closed, take the opportunity
    5380      * and do a limited wait (max. 1 second). This helps a lot when the system
    5381      * is busy and thus session closing can take a little while. */
    5382     if (    mData->mSession.mState == SessionState_Unlocking
    5383         &&  mData->mSession.mProgress)
    5384     {
    5385         alock.leave();
    5386         mData->mSession.mProgress->WaitForCompletion(1000);
    5387         alock.enter();
    5388         LogFlowThisFunc(("after waiting: mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
    5389     }
    5390 
    5391     if (    mData->mSession.mState == SessionState_Locked
    5392          || mData->mSession.mState == SessionState_Unlocking
    5393        )
    5394         return setError(VBOX_E_INVALID_OBJECT_STATE,
    5395                         tr("The machine '%ls' is already locked for a session (or being unlocked)"),
    5396                         mUserData->mName.raw());
    5397 
    5398     /* may not be busy */
    5399     AssertReturn(!Global::IsOnlineOrTransient(mData->mMachineState), E_FAIL);
    5400 
    5401     /* get the session PID */
    5402     RTPROCESS pid = NIL_RTPROCESS;
    5403     AssertCompile(sizeof(ULONG) == sizeof(RTPROCESS));
    5404     aControl->GetPID((ULONG *) &pid);
    5405     Assert(pid != NIL_RTPROCESS);
    5406 
    5407     if (mData->mSession.mState == SessionState_Spawning)
    5408     {
    5409         /* This machine is awaiting for a spawning session to be opened, so
    5410          * reject any other open attempts from processes other than one
    5411          * started by #openRemoteSession(). */
    5412 
    5413         LogFlowThisFunc(("mSession.mPid=%d(0x%x)\n",
    5414                           mData->mSession.mPid, mData->mSession.mPid));
    5415         LogFlowThisFunc(("session.pid=%d(0x%x)\n", pid, pid));
    5416 
    5417         if (mData->mSession.mPid != pid)
    5418             return setError(E_ACCESSDENIED,
    5419                             tr("An unexpected process (PID=0x%08X) has tried to lock the "
    5420                                "machine '%ls', while only the process started by launchVMProcess (PID=0x%08X) is allowed"),
    5421                             pid, mUserData->mName.raw(), mData->mSession.mPid);
    5422     }
    5423 
    5424     /* create a SessionMachine object */
    5425     ComObjPtr<SessionMachine> sessionMachine;
    5426     sessionMachine.createObject();
    5427     HRESULT rc = sessionMachine->init(this);
    5428     AssertComRC(rc);
    5429 
    5430     /* NOTE: doing return from this function after this point but
    5431      * before the end is forbidden since it may call SessionMachine::uninit()
    5432      * (through the ComObjPtr's destructor) which requests the VirtualBox write
    5433      * lock while still holding the Machine lock in alock so that a deadlock
    5434      * is possible due to the wrong lock order. */
    5435 
    5436     if (SUCCEEDED(rc))
    5437     {
    5438         /*
    5439          *  Set the session state to Spawning to protect against subsequent
    5440          *  attempts to open a session and to unregister the machine after
    5441          *  we leave the lock.
    5442          */
    5443         SessionState_T origState = mData->mSession.mState;
    5444         mData->mSession.mState = SessionState_Spawning;
    5445 
    5446         /*
    5447          *  Leave the lock before calling the client process -- it will call
    5448          *  Machine/SessionMachine methods. Leaving the lock here is quite safe
    5449          *  because the state is Spawning, so that openRemotesession() and
    5450          *  openExistingSession() calls will fail. This method, called before we
    5451          *  enter the lock again, will fail because of the wrong PID.
    5452          *
    5453          *  Note that mData->mSession.mRemoteControls accessed outside
    5454          *  the lock may not be modified when state is Spawning, so it's safe.
    5455          */
    5456         alock.leave();
    5457 
    5458         LogFlowThisFunc(("Calling AssignMachine()...\n"));
    5459         rc = aControl->AssignMachine(sessionMachine);
    5460         LogFlowThisFunc(("AssignMachine() returned %08X\n", rc));
    5461 
    5462         /* The failure may occur w/o any error info (from RPC), so provide one */
    5463         if (FAILED(rc))
    5464             setError(VBOX_E_VM_ERROR,
    5465                 tr("Failed to assign the machine to the session (%Rrc)"), rc);
    5466 
    5467         if (SUCCEEDED(rc) && origState == SessionState_Spawning)
    5468         {
    5469             /* complete the remote session initialization */
    5470 
    5471             /* get the console from the direct session */
    5472             ComPtr<IConsole> console;
    5473             rc = aControl->GetRemoteConsole(console.asOutParam());
    5474             ComAssertComRC(rc);
    5475 
    5476             if (SUCCEEDED(rc) && !console)
    5477             {
    5478                 ComAssert(!!console);
    5479                 rc = E_FAIL;
    5480             }
    5481 
    5482             /* assign machine & console to the remote session */
    5483             if (SUCCEEDED(rc))
    5484             {
    5485                 /*
    5486                  *  after openRemoteSession(), the first and the only
    5487                  *  entry in remoteControls is that remote session
    5488                  */
    5489                 LogFlowThisFunc(("Calling AssignRemoteMachine()...\n"));
    5490                 rc = mData->mSession.mRemoteControls.front()->
    5491                     AssignRemoteMachine(sessionMachine, console);
    5492                 LogFlowThisFunc(("AssignRemoteMachine() returned %08X\n", rc));
    5493 
    5494                 /* The failure may occur w/o any error info (from RPC), so provide one */
    5495                 if (FAILED(rc))
    5496                     setError(VBOX_E_VM_ERROR,
    5497                              tr("Failed to assign the machine to the remote session (%Rrc)"), rc);
    5498             }
    5499 
    5500             if (FAILED(rc))
    5501                 aControl->Uninitialize();
    5502         }
    5503 
    5504         /* enter the lock again */
    5505         alock.enter();
    5506 
    5507         /* Restore the session state */
    5508         mData->mSession.mState = origState;
    5509     }
    5510 
    5511     /* finalize spawning anyway (this is why we don't return on errors above) */
    5512     if (mData->mSession.mState == SessionState_Spawning)
    5513     {
    5514         /* Note that the progress object is finalized later */
    5515         /** @todo Consider checking mData->mSession.mProgress for cancellation
    5516          *        around here.  */
    5517 
    5518         /* We don't reset mSession.mPid here because it is necessary for
    5519          * SessionMachine::uninit() to reap the child process later. */
    5520 
    5521         if (FAILED(rc))
    5522         {
    5523             /* Close the remote session, remove the remote control from the list
    5524              * and reset session state to Closed (@note keep the code in sync
    5525              * with the relevant part in openSession()). */
    5526 
    5527             Assert(mData->mSession.mRemoteControls.size() == 1);
    5528             if (mData->mSession.mRemoteControls.size() == 1)
    5529             {
    5530                 ErrorInfoKeeper eik;
    5531                 mData->mSession.mRemoteControls.front()->Uninitialize();
    5532             }
    5533 
    5534             mData->mSession.mRemoteControls.clear();
    5535             mData->mSession.mState = SessionState_Unlocked;
    5536         }
    5537     }
    5538     else
    5539     {
    5540         /* memorize PID of the directly opened session */
    5541         if (SUCCEEDED(rc))
    5542             mData->mSession.mPid = pid;
    5543     }
    5544 
    5545     if (SUCCEEDED(rc))
    5546     {
    5547         /* memorize the direct session control and cache IUnknown for it */
    5548         mData->mSession.mDirectControl = aControl;
    5549         mData->mSession.mState = SessionState_Locked;
    5550         /* associate the SessionMachine with this Machine */
    5551         mData->mSession.mMachine = sessionMachine;
    5552 
    5553         /* request an IUnknown pointer early from the remote party for later
    5554          * identity checks (it will be internally cached within mDirectControl
    5555          * at least on XPCOM) */
    5556         ComPtr<IUnknown> unk = mData->mSession.mDirectControl;
    5557         NOREF(unk);
    5558     }
    5559 
    5560     /* Leave the lock since SessionMachine::uninit() locks VirtualBox which
    5561      * would break the lock order */
    5562     alock.leave();
    5563 
    5564     /* uninitialize the created session machine on failure */
    5565     if (FAILED(rc))
    5566         sessionMachine->uninit();
    5567 
    5568     LogFlowThisFunc(("rc=%Rhrc\n", rc));
    5569     LogFlowThisFuncLeave();
    5570     return rc;
    5571 }
    5572 
    5573 /**
    55745611 *  @note Locks this object for writing, calls the client process
    55755612 *        (inside the lock).
     
    57975834    mData->mSession.mState = SessionState_Spawning;
    57985835    mData->mSession.mType = strType;
    5799 
    5800     LogFlowThisFuncLeave();
    5801     return S_OK;
    5802 }
    5803 
    5804 
    5805 /**
    5806  *  @note Locks this object for writing, calls the client process
    5807  *        (outside the lock).
    5808  */
    5809 HRESULT Machine::openExistingSession(IInternalSessionControl *aControl)
    5810 {
    5811     LogFlowThisFuncEnter();
    5812 
    5813     AssertReturn(aControl, E_FAIL);
    5814 
    5815     AutoCaller autoCaller(this);
    5816     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    5817 
    5818     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    5819 
    5820     if (!mData->mRegistered)
    5821         return setError(E_UNEXPECTED,
    5822                         tr("The machine '%ls' is not registered"),
    5823                         mUserData->mName.raw());
    5824 
    5825     LogFlowThisFunc(("mSession.state=%s\n", Global::stringifySessionState(mData->mSession.mState)));
    5826 
    5827     if (mData->mSession.mState != SessionState_Locked)
    5828         return setError(VBOX_E_INVALID_SESSION_STATE,
    5829                         tr("The machine '%ls' is not currently locked for a session"),
    5830                         mUserData->mName.raw());
    5831 
    5832     ComAssertRet(!mData->mSession.mDirectControl.isNull(), E_FAIL);
    5833 
    5834     // copy member variables before leaving lock
    5835     ComPtr<IInternalSessionControl> pDirectControl = mData->mSession.mDirectControl;
    5836     ComObjPtr<SessionMachine> pSessionMachine = mData->mSession.mMachine;
    5837     AssertReturn(!pSessionMachine.isNull(), E_FAIL);
    5838 
    5839     /*
    5840      *  Leave the lock before calling the client process. It's safe here
    5841      *  since the only thing to do after we get the lock again is to add
    5842      *  the remote control to the list (which doesn't directly influence
    5843      *  anything).
    5844      */
    5845     alock.leave();
    5846 
    5847     // get the console from the direct session (this is a remote call)
    5848     ComPtr<IConsole> pConsole;
    5849     LogFlowThisFunc(("Calling GetRemoteConsole()...\n"));
    5850     HRESULT rc = pDirectControl->GetRemoteConsole(pConsole.asOutParam());
    5851     LogFlowThisFunc(("GetRemoteConsole() returned %08X\n", rc));
    5852     if (FAILED (rc))
    5853         /* The failure may occur w/o any error info (from RPC), so provide one */
    5854         return setError(VBOX_E_VM_ERROR,
    5855             tr("Failed to get a console object from the direct session (%Rrc)"), rc);
    5856 
    5857     ComAssertRet(!pConsole.isNull(), E_FAIL);
    5858 
    5859     /* attach the remote session to the machine */
    5860     LogFlowThisFunc(("Calling AssignRemoteMachine()...\n"));
    5861     rc = aControl->AssignRemoteMachine(pSessionMachine, pConsole);
    5862     LogFlowThisFunc(("AssignRemoteMachine() returned %08X\n", rc));
    5863 
    5864     /* The failure may occur w/o any error info (from RPC), so provide one */
    5865     if (FAILED(rc))
    5866         return setError(VBOX_E_VM_ERROR,
    5867                         tr("Failed to assign the machine to the session (%Rrc)"),
    5868                         rc);
    5869 
    5870     alock.enter();
    5871 
    5872     /* need to revalidate the state after entering the lock again */
    5873     if (mData->mSession.mState != SessionState_Locked)
    5874     {
    5875         aControl->Uninitialize();
    5876 
    5877         return setError(VBOX_E_INVALID_SESSION_STATE,
    5878                         tr("The machine '%ls' is not currently locked for a session"),
    5879                         mUserData->mName.raw());
    5880     }
    5881 
    5882     /* store the control in the list */
    5883     mData->mSession.mRemoteControls.push_back(aControl);
    58845836
    58855837    LogFlowThisFuncLeave();
  • trunk/src/VBox/Main/SessionImpl.cpp

    r31008 r31019  
    278278    AssertReturn(mState != SessionState_Unlocked, VBOX_E_INVALID_VM_STATE);
    279279
    280     AssertMsgReturn(mType == SessionType_Direct && !!mConsole,
     280    AssertMsgReturn(mType == SessionType_WriteLock && !!mConsole,
    281281                    ("This is not a direct session!\n"),
    282282                    VBOX_E_INVALID_OBJECT_STATE);
     
    345345    if (SUCCEEDED(rc))
    346346    {
    347         mType = SessionType_Direct;
     347        mType = SessionType_WriteLock;
    348348        mState = SessionState_Locked;
    349349    }
     
    458458
    459459    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    460     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     460    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    461461
    462462    AssertReturn(!mControl.isNull(), E_FAIL);
     
    522522    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    523523    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    524     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     524    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    525525
    526526    return mConsole->onNetworkAdapterChange(networkAdapter, changeAdapter);
     
    536536    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    537537    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    538     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     538    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    539539
    540540    return mConsole->onSerialPortChange(serialPort);
     
    550550    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    551551    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    552     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     552    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    553553
    554554    return mConsole->onParallelPortChange(parallelPort);
     
    564564    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    565565    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    566     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     566    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    567567
    568568    return mConsole->onStorageControllerChange();
     
    578578    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    579579    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    580     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     580    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    581581
    582582    return mConsole->onMediumChange(aMediumAttachment, aForce);
     
    592592    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    593593    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    594     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     594    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    595595
    596596    return mConsole->onCPUChange(aCPU, aRemove);
     
    606606    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    607607    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    608     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     608    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    609609
    610610    return mConsole->onVRDPServerChange(aRestart);
     
    620620    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    621621    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    622     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     622    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    623623
    624624    return mConsole->onUSBControllerChange();
     
    634634    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    635635    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    636     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     636    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    637637
    638638    return mConsole->onSharedFolderChange(aGlobal);
     
    650650    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    651651    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    652     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     652    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    653653
    654654    return mConsole->onUSBDeviceAttach(aDevice, aError, aMaskedIfs);
     
    665665    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    666666    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    667     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     667    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    668668
    669669    return mConsole->onUSBDeviceDetach(aId, aError);
     
    677677    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    678678
    679     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     679    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    680680
    681681    if (mState != SessionState_Locked)
     
    704704                        tr("Machine is not locked by session (session state: %s)."),
    705705                        Global::stringifySessionState(mState));
    706     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     706    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    707707    CheckComArgStrNotEmptyOrNull(aName);
    708708    if (!aIsSetter && !VALID_PTR(aRetValue))
     
    741741                        tr("Machine is not locked by session (session state: %s)."),
    742742                        Global::stringifySessionState(mState));
    743     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     743    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    744744    if (!VALID_PTR(aPatterns) && (aPatterns != NULL))
    745745        return E_POINTER;
     
    777777                        tr("Machine is not locked by session (session state: %s)."),
    778778                        Global::stringifySessionState(mState));
    779     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
     779    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    780780    CheckComArgNotNull(aMediumAttachment);
    781781    CheckComArgSafeArrayNotNull(aChildrenToReparent);
     
    847847    mState = SessionState_Unlocking;
    848848
    849     if (mType == SessionType_Direct)
     849    if (mType == SessionType_WriteLock)
    850850    {
    851851        mConsole->uninit();
     
    894894         *        VirtualBoxBase::addCaller.
    895895         */
    896         if (mType != SessionType_Direct && (rc == E_UNEXPECTED || rc == E_ACCESSDENIED))
     896        if (mType != SessionType_WriteLock && (rc == E_UNEXPECTED || rc == E_ACCESSDENIED))
    897897            rc = S_OK;
    898898
     
    902902    mControl.setNull();
    903903
    904     if (mType == SessionType_Direct)
     904    if (mType == SessionType_WriteLock)
    905905    {
    906906        releaseIPCSemaphore();
  • trunk/src/VBox/Main/VirtualBoxImpl.cpp

    r31008 r31019  
    37233723/**
    37243724 *  Thread function that watches the termination of all client processes
    3725  *  that have opened sessions using IMachine::LockForSession()
     3725 *  that have opened sessions using IMachine::LockMachine()
    37263726 */
    37273727// static
  • trunk/src/VBox/Main/glue/glue-java.xsl

    r31008 r31019  
    24972497    {
    24982498        ISession s = getSessionObject();
    2499         m.lockForSession(s, true /* fPermitShared */);
     2499        m.lockMachine(s, LockType.Shared);
    25002500        return s;
    25012501    }
     
    34593459    {
    34603460        ISession s = getSessionObject();
    3461         m.lockForSession(s, true /* fPermitShared */ );
     3461        m.lockMachine(s, LockType.Shared);
    34623462        return s;
    34633463    }
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r31008 r31019  
    818818        currently locked for this session, and the mutable machine object
    819819        can be found in the <link to="ISession::machine"/> attribute
    820         (see <link to="IMachine::lockForSession" /> for details).
     820        (see <link to="IMachine::lockMachine" /> for details).
    821821      </desc>
    822822    </const>
     
    825825        A new process is being spawned for the machine as a result of
    826826        <link to="IMachine::launchVMProcess"/> call. This state also occurs
    827         as a short transient state during an <link to="IMachine::lockForSession"/>
     827        as a short transient state during an <link to="IMachine::lockMachine"/>
    828828        call.
    829829      </desc>
     
    906906
    907907  <enum
     908   name="LockType"
     909   uuid="138b53f8-db4b-47c5-b32b-4ef52f769413"
     910  >
     911    <desc>
     912      Used with <link to="IMachine::lockMachine" />.
     913    </desc>
     914    <const name="Write" value="2">
     915      <desc>Lock the machine for writing.</desc>
     916    </const>
     917    <const name="Shared" value="1">
     918      <desc>Request only a shared read lock for remote-controlling the machine.</desc>
     919    </const>
     920  </enum>
     921
     922  <enum
    908923    name="SessionType"
    909924    uuid="A13C02CB-0C2C-421E-8317-AC0E8AAA153A"
     
    917932      <desc>Null value (never used by the API).</desc>
    918933    </const>
    919     <const name="Direct"                value="1">
    920       <desc>
    921         Direct session
    922         (used with <link to="IMachine::lockForSession"/>)
     934    <const name="WriteLock"             value="1">
     935      <desc>
     936        Session has acquired an exclusive write lock on a machine
     937        using <link to="IMachine::lockMachine"/>.
    923938      </desc>
    924939    </const>
    925940    <const name="Remote"                value="2">
    926941      <desc>
    927         Remote VM process
    928         (opened by <link to="IMachine::launchVMProcess"/>)
     942        Session has launched a VM process using
     943        <link to="IMachine::launchVMProcess"/>
    929944      </desc>
    930945    </const>
    931946    <const name="Shared"                value="3">
    932947      <desc>
    933         Shared session; remote link to an existing direct session opened
    934         by <link to="IMachine::lockForSession"/> with fPermitShared = true
     948        Session has obtained a link to another session using
     949        <link to="IMachine::lockMachine"/>
    935950      </desc>
    936951    </const>
     
    36553670
    36563671      In order to change a machine setting, a session for this machine must be
    3657       opened using one of the <link to="IMachine::lockForSession" /> or
     3672      opened using one of the <link to="IMachine::lockMachine" /> or
    36583673      <link to="IMachine::launchVMProcess"/> methods. After the
    36593674      machine has been successfully locked for a session, a mutable machine object
     
    39974012        same value as passed to the
    39984013        <link to="IMachine::launchVMProcess"/> method in the
    3999         @a type parameter. If the session was opened directly using
    4000         <link to="IMachine::lockForSession" />, or if
     4014        @a type parameter. If the session was used with
     4015        <link to="IMachine::lockMachine" />, or if
    40014016        <link to="#sessionState"/> is SessionClosed, the value of this
    40024017        attribute is an empty string.
     
    40074022      <desc>
    40084023        Identifier of the session process. This attribute contains the
    4009         platform-dependent identifier of the process that has opened a
    4010         direct session for this machine using the
    4011         <link to="IMachine::lockForSession" /> call. The returned value
    4012         is only valid if <link to="#sessionState"/> is SessionOpen or
    4013         SessionClosing (i.e. a session is currently open or being
    4014         closed) by the time this property is read.
     4024        platform-dependent identifier of the process whose session was
     4025        used with <link to="IMachine::lockMachine" /> call. The returned
     4026        value is only valid if <link to="#sessionState"/> is Locked or
     4027        Unlocking by the time this property is read.
    40154028      </desc>
    40164029    </attribute>
     
    41934206    </attribute>
    41944207
    4195     <method name="lockForSession">
     4208    <method name="lockMachine">
    41964209      <desc>
    41974210        Locks the machine for the given session to enable the caller
    4198         to make changes to the machine or start the VM.
    4199 
    4200         A single machine can only be locked for a single sesseion
    4201         at a time, protecting the VM from being manipulated by
    4202         conflicting actions from different processes. Only after this
    4203         method has been called, one can change all VM settings
    4204         or execute the VM in the process space of the session object.
    4205         See <link to="ISession">ISession</link> for details.
    4206 
    4207         Locking the machine for a session creates a second copy of
    4208         the IMachine object. It is this second object upon which
    4209         changes can be made; in VirtualBox terminology, the second
    4210         copy is "mutable". It is only this second, mutable machine
    4211         object upon which you can call methods that change the
    4212         machine state. After having called this method, you can
    4213         obtain this second, mutable machine object using the
    4214         <link to="ISession::machine" /> attribute. This way, you can
    4215         also get access to the <link to="IConsole" /> object which
    4216         controls VM execution.
    4217 
    4218         <note>Unless you are writing a new VM frontend, you will not
    4219         want to execute a VM in the current process. To spawn a new
    4220         process that executes a VM, use <link to="IMachine::launchVMProcess" />
    4221         instead.</note>
    4222 
    4223         One must always call <link to="ISession::close" /> to release the
    4224         lock on the machine, or the machine's state will eventually be
    4225         set to "Aborted".
    4226 
    4227         In other words, to change settings on a machine, the following
    4228         sequence is typically performed:
     4211        to make changes to the machine or start the VM or control
     4212        VM execution.
     4213
     4214        There are two ways to lock a machine for such uses:
     4215
     4216        <ul>
     4217          <li>If you want to make changes to the machine settings,
     4218            you must obtain an exclusive write lock on the machine
     4219            by setting @a lockType to @c Write.
     4220
     4221            This will only succeed if no other process has locked
     4222            the machine to prevent conflicting changes. Only after
     4223            an exclusive write lock has been obtained using this method, one
     4224            can change all VM settings or execute the VM in the process
     4225            space of the session object. (Note that the latter is only of
     4226            interest if you actually want to write a new front-end for
     4227            virtual machines; but this API gets called internally by
     4228            the existing front-ends such as VBoxHeadless and the VirtualBox
     4229            GUI to acquire a write lock on the machine that they are running.)
     4230
     4231            On success, write-locking the machine for a session creates
     4232            a second copy of the IMachine object. It is this second object
     4233            upon which changes can be made; in VirtualBox terminology, the
     4234            second copy is "mutable". It is only this second, mutable machine
     4235            object upon which you can call methods that change the
     4236            machine state. After having called this method, you can
     4237            obtain this second, mutable machine object using the
     4238            <link to="ISession::machine" /> attribute.
     4239          </li>
     4240          <li>If you only want to check the machine state or control
     4241            machine execution without actually changing machine
     4242            settings (e.g. to get access to VM statistics or take
     4243            a snapshot or save the machine state), then set the
     4244            @a lockType argument to @c Shared.
     4245
     4246            If no other session has obtained a lock, you will obtain an
     4247            exclusive write lock as described above. However, if another
     4248            session has already obtained such a lock, then a link to that
     4249            existing session will be established which allows you
     4250            to control that existing session.
     4251
     4252            To find out which type of lock was obtained, you can
     4253            inspect <link to="ISession::type" />, which will have been
     4254            set to either @c WriteLock or @c Shared.
     4255          </li>
     4256        </ul>
     4257
     4258        In either case, you can get access to the <link to="IConsole" />
     4259        object which controls VM execution.
     4260
     4261        Also in all of the above cases, one must always call <link to="ISession::close" />
     4262        to release the lock on the machine, or the machine's state will
     4263        eventually be set to "Aborted".
     4264
     4265        To change settings on a machine, the following sequence is typically
     4266        performed:
    42294267
    42304268        <ol>
    4231           <li>Call this method (openSession) to have a machine locked for
    4232             the current session.</li>
     4269          <li>Call this method to obtain an exclusive write lock for the current session.</li>
    42334270
    42344271          <li>Obtain a mutable IMachine object from <link to="ISession::machine" />.</li>
     
    42414278        </ol>
    42424279
    4243         If the @a fPermitShared parameter is set to true, this method will also
    4244         succeed on a machine which has already been locked by another session.
    4245         The caller will then be attached to that existing session, and its own
    4246         session will be marked as "Shared". While not all machine settings can
    4247         be changed in that case, an IConsole object will still be created which
    4248         provides to the caller some level of control over the VM execution, for
    4249         example to pause the machine. The number of such shared sessions per
    4250         machine is not limited by the API.
    4251 
    4252         The return value will then indicate whether a direct session was opened
    4253         (<link to="SessionType::Direct" />) or whether an existing direct session
    4254         was shared ((<link to="SessionType::Shared" />).
    4255 
    4256         If the @a fPermitShared parameter is @c false, then this can only
    4257         possibly return <link to="SessionType::Direct" />.
    4258 
    42594280        <result name="E_UNEXPECTED">
    42604281          Virtual machine not registered.
     
    42754296        </desc>
    42764297      </param>
    4277       <param name="fPermitShared" type="boolean" dir="in">
    4278         <desc>
    4279           Whether to allow for sharing a direct session remotely.
    4280         </desc>
    4281       </param>
    4282       <param name="sessionType" type="SessionType" dir="return">
    4283         <desc>
     4298      <param name="lockType" type="LockType" dir="in">
     4299        <desc>
     4300          If set to @c Write, then attempt to acquire an exclusive write lock or fail.
     4301          If set to @c Shared, then either acquire an exclusive write lock or establish
     4302          a link to an existing session.
    42844303        </desc>
    42854304      </param>
     
    43124331        object which can be used to control machine execution, but it cannot
    43134332        be used to change all VM settings which would be available after
    4314         a <link to="#lockForSession" /> call.
     4333        a <link to="#lockMachine" /> call.
    43154334
    43164335        As with all <link to="ISession" /> objects, it is recommended to call
     
    59245943
    59255944      A console object gets created when a machine has been locked for a
    5926       particular session (client process) using <link to="IMachine::lockForSession" />
     5945      particular session (client process) using <link to="IMachine::lockMachine" />
    59275946      or <link to="IMachine::launchVMProcess"/>. The console object can
    59285947      then be found in the session's <link to="ISession::console" /> attribute.
     
    1275512774      <ul>
    1275612775        <li>To alter machine settings, one needs to lock a machine for a given session
    12757           (client process) by calling <link to="IMachine::lockForSession"/>. While a
     12776          (client process) by calling <link to="IMachine::lockMachine"/>. While a
    1275812777          machine is thus locked, no any other process may lock the machine again.
    1275912778
     
    1282312842        Calling this method is eventually required every time a machine has been
    1282412843        locked for a particular session using the <link to="IMachine::launchVMProcess" />
    12825         or <link to="IMachine::lockForSession" />) calls. Otherwise the state of
     12844        or <link to="IMachine::lockMachine" />) calls. Otherwise the state of
    1282612845        the machine will be set to <link to="MachineState_Aborted" /> on the
    1282712846        server, and changes made to the machine settings will be lost.
  • trunk/src/VBox/Main/include/MachineImpl.h

    r31008 r31019  
    115115        struct Session
    116116        {
    117             /** Control of the direct session opened by lockForSession() */
     117            /** Control of the direct session opened by lockMachine() */
    118118            ComPtr<IInternalSessionControl> mDirectControl;
    119119
     
    455455
    456456    // IMachine methods
    457     STDMETHOD(LockForSession)(ISession *aSession, BOOL fPermitShared, SessionType_T *sessionType);
     457    STDMETHOD(LockMachine)(ISession *aSession, LockType_T lockType);
    458458    STDMETHOD(LaunchVMProcess)(ISession *aSession,  IN_BSTR aType, IN_BSTR aEnvironment, IProgress **aProgress);
    459459
     
    627627    Utf8Str queryLogFilename(ULONG idx);
    628628
    629     HRESULT openSession(IInternalSessionControl *aControl);
    630629    HRESULT openRemoteSession(IInternalSessionControl *aControl,
    631630                              IN_BSTR aType, IN_BSTR aEnvironment,
    632631                              ProgressProxy *aProgress);
    633     HRESULT openExistingSession(IInternalSessionControl *aControl);
    634632
    635633    HRESULT getDirectControl(ComPtr<IInternalSessionControl> *directControl)
  • trunk/src/VBox/Main/testcase/tstVBoxAPILinux.cpp

    r31008 r31019  
    266266        }
    267267
    268         machine->LockForSession(session, false /* fPermitShared */, NULL);
     268        machine->LockMachine(session, LockType_Write);
    269269        if (NS_FAILED(rc))
    270270        {
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