VirtualBox

Changeset 33848 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 8, 2010 2:29:13 PM (14 years ago)
Author:
vboxsync
Message:

Main/Console+Machine: move progress object for Console::SaveState from the VM process to VBoxSVC

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

Legend:

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

    r33842 r33848  
    240240struct VMSaveTask : public VMProgressTask
    241241{
    242     VMSaveTask(Console *aConsole, Progress *aProgress)
     242    VMSaveTask(Console *aConsole, Progress *aProgress, const ComPtr<IProgress> &aServerProgress)
    243243        : VMProgressTask(aConsole, aProgress, true /* aUsesVMPtr */),
    244           mLastMachineState(MachineState_Null)
     244          mLastMachineState(MachineState_Null),
     245          mServerProgress(aServerProgress)
    245246    {}
    246247
     
    23182319
    23192320    HRESULT rc = S_OK;
    2320 
    2321     /* create a progress object to track operation completion */
    2322     ComObjPtr<Progress> progress;
    2323     progress.createObject();
    2324     progress->init(static_cast<IConsole *>(this),
    2325                    Bstr(tr("Saving the execution state of the virtual machine")).raw(),
    2326                    FALSE /* aCancelable */);
    2327 
    23282321    bool fBeganSavingState = false;
    23292322    bool fTaskCreationFailed = false;
     
    23312324    do
    23322325    {
     2326        ComPtr<IProgress> pProgress;
     2327        Bstr stateFilePath;
     2328
     2329        /*
     2330         * request a saved state file path from the server
     2331         * (this will set the machine state to Saving on the server to block
     2332         * others from accessing this machine)
     2333         */
     2334        rc = mControl->BeginSavingState(pProgress.asOutParam(),
     2335                                        stateFilePath.asOutParam());
     2336        if (FAILED(rc)) break;
     2337
     2338        fBeganSavingState = true;
     2339
     2340        /* sync the state with the server */
     2341        setMachineStateLocally(MachineState_Saving);
     2342
    23332343        /* create a task object early to ensure mpVM protection is successful */
    2334         std::auto_ptr <VMSaveTask> task(new VMSaveTask(this, progress));
     2344        std::auto_ptr <VMSaveTask> task(new VMSaveTask(this, NULL, pProgress));
    23352345        rc = task->rc();
    23362346        /*
     
    23452355            break;
    23462356        }
    2347 
    2348         Bstr stateFilePath;
    2349 
    2350         /*
    2351          * request a saved state file path from the server
    2352          * (this will set the machine state to Saving on the server to block
    2353          * others from accessing this machine)
    2354          */
    2355         rc = mControl->BeginSavingState(progress, stateFilePath.asOutParam());
    2356         if (FAILED(rc)) break;
    2357 
    2358         fBeganSavingState = true;
    2359 
    2360         /* sync the state with the server */
    2361         setMachineStateLocally(MachineState_Saving);
    23622357
    23632358        /* ensure the directory for the saved state file exists */
     
    23962391
    23972392        /* return the progress to the caller */
    2398         progress.queryInterfaceTo(aProgress);
     2393        pProgress.queryInterfaceTo(aProgress);
    23992394    }
    24002395    while (0);
     
    24122407             * before calling mControl->BeginSavingState().
    24132408             */
    2414             mControl->EndSavingState(FALSE);
     2409            mControl->EndSavingState(eik.getResultCode(), eik.getText().raw());
    24152410        }
    24162411
     
    35053500 * @note Locks this object for writing.
    35063501 */
    3507 HRESULT Console::onNATRedirectRuleChange(INetworkAdapter *aNetworkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName, 
     3502HRESULT Console::onNATRedirectRuleChange(INetworkAdapter *aNetworkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName,
    35083503                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
    35093504{
     
    35543549        vrc = aNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
    35553550
    3556         if (   RT_FAILURE(vrc) 
     3551        if (   RT_FAILURE(vrc)
    35573552            || attachmentType != NetworkAttachmentType_NAT)
    35583553        {
     
    35603555            goto done;
    35613556        }
    3562        
     3557
    35633558        /* look down for PDMINETWORKNATCONFIG interface */
    35643559        while (pBase)
     
    35723567            goto done;
    35733568        bool fUdp = (aProto == NATProtocol_UDP);
    3574         vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, Utf8Str(aRuleName).c_str(), fUdp, 
    3575                                                  Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(), 
     3569        vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, Utf8Str(aRuleName).c_str(), fUdp,
     3570                                                 Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
    35763571                                                 aGuestPort);
    35773572        if (RT_FAILURE(vrc))
     
    63686363                    break;
    63696364                case MachineState_Saving:
    6370                     /* successfully saved (note that the machine is already in
    6371                      * the Saved state on the server due to EndSavingState()
    6372                      * called from saveStateThread(), so only change the local
    6373                      * state) */
    6374                     that->setMachineStateLocally(MachineState_Saved);
     6365                    /* successfully saved */
     6366                    that->setMachineState(MachineState_Saved);
    63756367                    break;
    63766368                case MachineState_Starting:
     
    70697061 * @param   pVM         The VM handle.
    70707062 * @param   uPercent    Completion percentage (0-100).
    7071  * @param   pvUser      Pointer to the VMProgressTask structure.
     7063 * @param   pvUser      Pointer to an IProgress instance.
    70727064 * @return  VINF_SUCCESS.
    70737065 */
     
    70757067DECLCALLBACK(int) Console::stateProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
    70767068{
    7077     VMProgressTask *task = static_cast<VMProgressTask *>(pvUser);
    7078     AssertReturn(task, VERR_INVALID_PARAMETER);
     7069    IProgress *pProgress = static_cast<IProgress *>(pvUser);
    70797070
    70807071    /* update the progress object */
    7081     if (task->mProgress)
    7082         task->mProgress->SetCurrentOperationProgress(uPercent);
     7072    if (pProgress)
     7073        pProgress->SetCurrentOperationProgress(uPercent);
    70837074
    70847075    return VINF_SUCCESS;
     
    76137604                                           task->mSavedStateFile.c_str(),
    76147605                                           Console::stateProgressCallback,
    7615                                            static_cast<VMProgressTask*>(task.get()));
     7606                                           static_cast<IProgress *>(task->mProgress));
    76167607
    76177608                    if (RT_SUCCESS(vrc))
     
    80057996                               true /*fContinueAfterwards*/,
    80067997                               Console::stateProgressCallback,
    8007                                (void*)pTask,
     7998                               static_cast<IProgress *>(pTask->mProgress),
    80087999                               &fSuspenededBySave);
    80098000            alock.enter();
     
    82518242
    82528243    Assert(task->mSavedStateFile.length());
    8253     Assert(!task->mProgress.isNull());
     8244    Assert(task->mProgress.isNull());
     8245    Assert(!task->mServerProgress.isNull());
    82548246
    82558247    const ComObjPtr<Console> &that = task->mConsole;
     
    82648256                       false, /*fContinueAfterwards*/
    82658257                       Console::stateProgressCallback,
    8266                        static_cast<VMProgressTask*>(task.get()),
     8258                       static_cast<IProgress *>(task->mServerProgress),
    82678259                       &fSuspenededBySave);
    82688260    if (RT_FAILURE(vrc))
     
    82778269    AutoWriteLock thatLock(that COMMA_LOCKVAL_SRC_POS);
    82788270
    8279     /*
    8280      * finalize the requested save state procedure.
    8281      * In case of success, the server will set the machine state to Saved;
    8282      * in case of failure it will reset the it to the state it had right
    8283      * before calling mControl->BeginSavingState().
    8284      */
    8285     that->mControl->EndSavingState(SUCCEEDED(rc));
    8286 
    82878271    /* synchronize the state with the server */
    8288     if (!FAILED(rc))
     8272    if (SUCCEEDED(rc))
    82898273    {
    82908274        /*
     
    82958279         */
    82968280        task->releaseVMCaller();
    8297 
    82988281        rc = that->powerDown();
    82998282    }
    83008283
    8301     /* notify the progress object about operation completion */
    8302     if (SUCCEEDED(rc))
    8303         task->mProgress->notifyComplete(S_OK);
    8304     else
    8305     {
    8306         if (errMsg.length())
    8307             task->mProgress->notifyComplete(rc,
    8308                                             COM_IIDOF(IConsole),
    8309                                             Console::getStaticComponentName(),
    8310                                             errMsg.c_str());
    8311         else
    8312             task->mProgress->notifyComplete(rc);
    8313     }
     8284    /*
     8285     * Finalize the requested save state procedure. In case of failure it will
     8286     * reset the machine state to the state it had right before calling
     8287     * mControl->BeginSavingState(). This must be the last thing because it
     8288     * will set the progress to completed, and that means that the frontend
     8289     * can immediately uninit the associated console object.
     8290     */
     8291    that->mControl->EndSavingState(rc, Bstr(errMsg).raw());
    83148292
    83158293    LogFlowFuncLeave();
  • trunk/src/VBox/Main/MachineImpl.cpp

    r33825 r33848  
    32163216    CheckComArgNotNull(aSession);
    32173217    CheckComArgStrNotEmptyOrNull(aType);
    3218     CheckComArgOutSafeArrayPointerValid(aProgress);
     3218    CheckComArgOutPointerValid(aProgress);
    32193219
    32203220    AutoCaller autoCaller(this);
     
    1003510035    {
    1003610036        LogWarningThisFunc(("canceling failed save state request!\n"));
    10037         endSavingState(FALSE /* aSuccess  */);
     10037        endSavingState(E_FAIL, tr("Machine terminated with pending save state!"));
    1003810038    }
    1003910039    else if (!mSnapshotData.mSnapshot.isNull())
     
    1052810528 *  @note Locks this object for writing.
    1052910529 */
    10530 STDMETHODIMP SessionMachine::BeginSavingState(IProgress *aProgress, BSTR *aStateFilePath)
     10530STDMETHODIMP SessionMachine::BeginSavingState(IProgress **aProgress, BSTR *aStateFilePath)
    1053110531{
    1053210532    LogFlowThisFuncEnter();
    1053310533
    10534     AssertReturn(aProgress, E_INVALIDARG);
    10535     AssertReturn(aStateFilePath, E_POINTER);
     10534    CheckComArgOutPointerValid(aProgress);
     10535    CheckComArgOutPointerValid(aStateFilePath);
    1053610536
    1053710537    AutoCaller autoCaller(this);
     
    1054210542    AssertReturn(    mData->mMachineState == MachineState_Paused
    1054310543                  && mSnapshotData.mLastState == MachineState_Null
    10544                   && mSnapshotData.mProgressId.isEmpty()
    1054510544                  && mSnapshotData.mStateFilePath.isEmpty(),
    1054610545                 E_FAIL);
    1054710546
    10548     /* memorize the progress ID and add it to the global collection */
    10549     Bstr progressId;
    10550     HRESULT rc = aProgress->COMGETTER(Id)(progressId.asOutParam());
    10551     AssertComRCReturn(rc, rc);
    10552     rc = mParent->addProgress(aProgress);
    10553     AssertComRCReturn(rc, rc);
     10547    /* create a progress object to track operation completion */
     10548    ComObjPtr<Progress> pProgress;
     10549    pProgress.createObject();
     10550    pProgress->init(getVirtualBox(),
     10551                    static_cast<IMachine *>(this) /* aInitiator */,
     10552                    Bstr(tr("Saving the execution state of the virtual machine")).raw(),
     10553                    FALSE /* aCancelable */);
    1055410554
    1055510555    Bstr stateFilePath;
     
    1056410564    /* fill in the snapshot data */
    1056510565    mSnapshotData.mLastState = mData->mMachineState;
    10566     mSnapshotData.mProgressId = Guid(progressId);
    1056710566    mSnapshotData.mStateFilePath = stateFilePath;
     10567    mSnapshotData.mProgress = pProgress;
    1056810568
    1056910569    /* set the state to Saving (this is expected by Console::SaveState()) */
     
    1057110571
    1057210572    stateFilePath.cloneTo(aStateFilePath);
     10573    pProgress.queryInterfaceTo(aProgress);
    1057310574
    1057410575    return S_OK;
     
    1057810579 *  @note Locks mParent + this object for writing.
    1057910580 */
    10580 STDMETHODIMP SessionMachine::EndSavingState(BOOL aSuccess)
     10581STDMETHODIMP SessionMachine::EndSavingState(LONG iResult, IN_BSTR aErrMsg)
    1058110582{
    1058210583    LogFlowThisFunc(("\n"));
     
    1058810589    AutoMultiWriteLock2 alock(mParent, this COMMA_LOCKVAL_SRC_POS);
    1058910590
    10590     AssertReturn(    mData->mMachineState == MachineState_Saving
     10591    AssertReturn(    (   (SUCCEEDED(iResult) && mData->mMachineState == MachineState_Saved)
     10592                      || (FAILED(iResult) && mData->mMachineState == MachineState_Saving))
    1059110593                  && mSnapshotData.mLastState != MachineState_Null
    10592                   && !mSnapshotData.mProgressId.isEmpty()
    1059310594                  && !mSnapshotData.mStateFilePath.isEmpty(),
    1059410595                 E_FAIL);
    1059510596
    1059610597    /*
    10597      *  on success, set the state to Saved;
    10598      *  on failure, set the state to the state we had when BeginSavingState() was
    10599      *  called (this is expected by Console::SaveState() and
    10600      *  Console::saveStateThread())
     10598     * On failure, set the state to the state we had when BeginSavingState()
     10599     * was called (this is expected by Console::SaveState() and the associated
     10600     * task). On success the VM process already changed the state to
     10601     * MachineState_Saved, so no need to do anything.
    1060110602     */
    10602     if (aSuccess)
    10603         setMachineState(MachineState_Saved);
    10604     else
     10603    if (FAILED(iResult))
    1060510604        setMachineState(mSnapshotData.mLastState);
    1060610605
    10607     return endSavingState(aSuccess);
     10606    return endSavingState(iResult, aErrMsg);
    1060810607}
    1060910608
     
    1125911258 *  @note Must be called from under this object's lock.
    1126011259 *
    11261  *  @param aSuccess TRUE if the snapshot has been taken successfully
     11260 *  @param aRc      S_OK if the snapshot has been taken successfully
     11261 *  @param aErrMsg  human readable error message for failure
    1126211262 *
    1126311263 *  @note Locks mParent + this objects for writing.
    1126411264 */
    11265 HRESULT SessionMachine::endSavingState(BOOL aSuccess)
     11265HRESULT SessionMachine::endSavingState(HRESULT aRc, const Utf8Str &aErrMsg)
    1126611266{
    1126711267    LogFlowThisFuncEnter();
     
    1127411274    HRESULT rc = S_OK;
    1127511275
    11276     if (aSuccess)
     11276    if (SUCCEEDED(aRc))
    1127711277    {
    1127811278        mSSData->mStateFilePath = mSnapshotData.mStateFilePath;
     
    1128911289    }
    1129011290
    11291     /* remove the completed progress object */
    11292     mParent->removeProgress(mSnapshotData.mProgressId.ref());
     11291    /* notify the progress object about operation completion */
     11292    Assert(mSnapshotData.mProgress);
     11293    if (SUCCEEDED(aRc))
     11294        mSnapshotData.mProgress->notifyComplete(S_OK);
     11295    else
     11296    {
     11297        if (aErrMsg.length())
     11298            mSnapshotData.mProgress->notifyComplete(aRc,
     11299                                                    COM_IIDOF(ISession),
     11300                                                    getComponentName(),
     11301                                                    aErrMsg.c_str());
     11302        else
     11303            mSnapshotData.mProgress->notifyComplete(aRc);
     11304    }
    1129311305
    1129411306    /* clear out the temporary saved state data */
    1129511307    mSnapshotData.mLastState = MachineState_Null;
    11296     mSnapshotData.mProgressId.clear();
    1129711308    mSnapshotData.mStateFilePath.setNull();
     11309    mSnapshotData.mProgress.setNull();
    1129811310
    1129911311    LogFlowThisFuncLeave();
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r33825 r33848  
    29452945  <interface
    29462946     name="IInternalMachineControl" extends="$unknown"
    2947      uuid="e2da8b1a-2ad1-490e-b29e-c33a144791b6"
     2947     uuid="476126af-e223-4490-a8a0-b1f1575be013"
    29482948     internal="yes"
    29492949     wsmap="suppress"
     
    30873087        save the current state and stop the VM execution.
    30883088      </desc>
    3089       <param name="progress" type="IProgress" dir="in">
    3090         <desc>
    3091           Progress object created by the VM process to wait until
     3089      <param name="progress" type="IProgress" dir="out">
     3090        <desc>
     3091          Progress object created by VBoxSVC to wait until
    30923092          the state is saved.
    30933093        </desc>
     
    31153115      </desc>
    31163116
    3117       <param name="success" type="boolean" dir="in">
    3118         <desc>@c true to indicate success and @c false otherwise.
     3117      <param name="result" type="long" dir="in">
     3118        <desc>@c S_OK to indicate success.
     3119        </desc>
     3120      </param>
     3121      <param name="errMsg" type="wstring" dir="in">
     3122        <desc>@c human readable error message in case of failure.
    31193123        </desc>
    31203124      </param>
  • trunk/src/VBox/Main/include/MachineImpl.h

    r33825 r33848  
    2121#include "VirtualBoxBase.h"
    2222#include "SnapshotImpl.h"
     23#include "ProgressImpl.h"
    2324#include "VRDEServerImpl.h"
    2425#include "MediumAttachmentImpl.h"
     
    918919    STDMETHOD(DetachAllUSBDevices)(BOOL aDone);
    919920    STDMETHOD(OnSessionEnd)(ISession *aSession, IProgress **aProgress);
    920     STDMETHOD(BeginSavingState)(IProgress *aProgress, BSTR *aStateFilePath);
    921     STDMETHOD(EndSavingState)(BOOL aSuccess);
     921    STDMETHOD(BeginSavingState)(IProgress **aProgress, BSTR *aStateFilePath);
     922    STDMETHOD(EndSavingState)(LONG aResult, IN_BSTR aErrMsg);
    922923    STDMETHOD(AdoptSavedState)(IN_BSTR aSavedStateFile);
    923924    STDMETHOD(BeginTakingSnapshot)(IConsole *aInitiator,
     
    987988
    988989        // used when saving state
    989         Guid mProgressId;
    990990        Utf8Str mStateFilePath;
     991        ComObjPtr<Progress> mProgress;
    991992    };
    992993
     
    10051006    void uninit(Uninit::Reason aReason);
    10061007
    1007     HRESULT endSavingState(BOOL aSuccess);
     1008    HRESULT endSavingState(HRESULT aRC, const Utf8Str &aErrMsg);
    10081009
    10091010    void deleteSnapshotHandler(DeleteSnapshotTask &aTask);
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