VirtualBox

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


Ignore:
Timestamp:
Oct 15, 2009 5:00:44 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53553
Message:

Main: Cancelling teleporation...

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

Legend:

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

    r23801 r23810  
    46354635        progressDesc = tr("Starting virtual machine");
    46364636    rc = powerupProgress->init(static_cast<IConsole *>(this),
    4637                                progressDesc, FALSE /* aCancelable */);
     4637                               progressDesc,
     4638                               fTeleporterEnabled /* aCancelable */);
    46384639    CheckComRCReturnRC(rc);
    46394640
     
    67636764                {
    67646765                    /* -> ConsoleImplTeleporter.cpp */
    6765                     vrc = console->teleporterTrg(pVM, pMachine, task->mStartPaused,
    6766                                                  static_cast<VMProgressTask*>(task.get()));
     6766                    vrc = console->teleporterTrg(pVM, pMachine, task->mStartPaused, task->mProgress);
    67676767                    if (RT_FAILURE(vrc))
    67686768                        VMR3PowerOff(pVM);
  • trunk/src/VBox/Main/ConsoleImplTeleporter.cpp

    r23806 r23810  
    5454    ComPtr<Console>     mptrConsole;
    5555    PVM                 mpVM;
     56    ComObjPtr<Progress> mptrProgress;
    5657    Utf8Str             mstrPassword;
    5758    bool const          mfIsSource;
     
    6768    /** @} */
    6869
    69     TeleporterState(Console *pConsole, PVM pVM, bool fIsSource)
     70    TeleporterState(Console *pConsole, PVM pVM, Progress *pProgress, bool fIsSource)
    7071        : mptrConsole(pConsole)
    7172        , mpVM(pVM)
     73        , mptrProgress(pProgress)
    7274        , mfIsSource(fIsSource)
    7375        , mhSocket(NIL_RTSOCKET)
     
    8890{
    8991public:
    90     ComPtr<Progress>    mptrProgress;
    9192    Utf8Str             mstrHostname;
    9293    uint32_t            muPort;
    9394
    94     TeleporterStateSrc(Console *pConsole, PVM pVM)
    95         : TeleporterState(pConsole, pVM, true /*fIsSource*/)
     95    TeleporterStateSrc(Console *pConsole, PVM pVM, Progress *pProgress)
     96        : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/)
    9697        , muPort(UINT32_MAX)
    9798    {
     
    107108public:
    108109    IMachine           *mpMachine;
    109     void               *mpvVMCallbackTask;
    110110    PRTTCPSERVER        mhServer;
    111111    PRTTIMERLR          mphTimerLR;
    112112    int                 mRc;
    113113
    114     TeleporterStateTrg(Console *pConsole, PVM pVM, IMachine *pMachine, PRTTIMERLR phTimerLR)
    115         : TeleporterState(pConsole, pVM, false /*fIsSource*/)
     114    TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
     115                       IMachine *pMachine, PRTTIMERLR phTimerLR)
     116        : TeleporterState(pConsole, pVM, pProgress, false /*fIsSource*/)
    116117        , mpMachine(pMachine)
    117         , mpvVMCallbackTask(NULL)
    118118        , mhServer(NULL)
    119119        , mphTimerLR(phTimerLR)
     
    496496
    497497/**
     498 * Progress cancelation callback.
     499 */
     500static void teleporterProgressCancelCallback(void *pvUser)
     501{
     502    TeleporterState *pState = (TeleporterState *)pvUser;
     503    SSMR3Cancel(pState->mpVM);
     504    if (!pState->mfIsSource)
     505    {
     506        TeleporterStateTrg *pStateTrg = (TeleporterStateTrg *)pState;
     507        RTTcpServerShutdown(pStateTrg->mhServer);
     508    }
     509}
     510
     511/**
     512 * @copydoc PFNVMPROGRESS
     513 */
     514static DECLCALLBACK(int) teleporterProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
     515{
     516    TeleporterState *pState = (TeleporterState *)pvUser;
     517    if (pState->mptrProgress)
     518    {
     519        HRESULT hrc = pState->mptrProgress->SetCurrentOperationProgress(uPercent);
     520        if (FAILED(hrc))
     521        {
     522            /* check if the failure was caused by cancellation. */
     523            BOOL fCanceled;
     524            hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCanceled);
     525            if (SUCCEEDED(hrc) && fCanceled)
     526            {
     527                SSMR3Cancel(pState->mpVM);
     528                return VERR_SSM_CANCELLED;
     529            }
     530        }
     531    }
     532
     533    return VINF_SUCCESS;
     534}
     535
     536
     537/**
    498538 * @copydoc FNRTTIMERLR
    499539 */
    500 static DECLCALLBACK(void) teleporterTimeout(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
     540static DECLCALLBACK(void) teleporterDstTimeout(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
    501541{
    502542    /* This is harmless for any open connections. */
     
    573613
    574614    void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
    575     vrc = VMR3Teleport(pState->mpVM, &g_teleporterTcpOps, pvUser, NULL/** @todo progress*/, pvUser);
     615    vrc = VMR3Teleport(pState->mpVM, &g_teleporterTcpOps, pvUser, teleporterProgressCallback, pvUser);
    576616    if (vrc)
    577617        return setError(E_FAIL, tr("VMR3Teleport -> %Rrc"), vrc);
     
    660700        pState->mhSocket = NIL_RTSOCKET;
    661701    }
     702
     703    pState->mptrProgress->setCancelCallback(NULL, NULL);
    662704    delete pState;
    663705
     
    713755    LogFlowThisFunc(("Initiating TELEPORTER request...\n"));
    714756
    715     ComObjPtr<Progress> ptrTelportationProgress;
    716     HRESULT hrc = ptrTelportationProgress.createObject();
     757    ComObjPtr<Progress> ptrProgress;
     758    HRESULT hrc = ptrProgress.createObject();
    717759    CheckComRCReturnRC(hrc);
    718     hrc = ptrTelportationProgress->init(static_cast<IConsole *>(this),
     760    hrc = ptrProgress->init(static_cast<IConsole *>(this),
    719761                                        Bstr(tr("Teleporter")),
    720762                                        TRUE /*aCancelable*/);
    721763    CheckComRCReturnRC(hrc);
    722764
    723     TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM);
     765    TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM, ptrProgress);
    724766    pState->mstrPassword = aPassword;
    725767    pState->mstrHostname = aHostname;
    726768    pState->muPort       = aPort;
    727     pState->mptrProgress = ptrTelportationProgress;
     769
     770    void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
     771    ptrProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser);
    728772
    729773    int vrc = RTThreadCreate(NULL, Console::teleporterSrcThreadWrapper, (void *)pState, 0 /*cbStack*/,
     
    733777        hrc = setMachineState(MachineState_Saving);
    734778        if (SUCCEEDED(hrc))
    735             ptrTelportationProgress.queryInterfaceTo(aProgress);
     779            ptrProgress.queryInterfaceTo(aProgress);
    736780        else
    737             ptrTelportationProgress->Cancel();
     781            ptrProgress->Cancel();
    738782    }
    739783    else
    740784    {
     785        ptrProgress->setCancelCallback(NULL, NULL);
    741786        delete pState;
    742787        hrc = setError(E_FAIL, tr("RTThreadCreate -> %Rrc"), vrc);
     
    756801 * @param   fStartPaused        Whether to start it in the Paused (true) or
    757802 *                              Running (false) state,
    758  * @param   pvVMCallbackTask    The callback task pointer for
    759  *                              stateProgressCallback().
     803 * @param   pProgress           Pointer to the progress object.
    760804 */
    761805int
    762 Console::teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, void *pvVMCallbackTask)
     806Console::teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, Progress *pProgress)
    763807{
    764808    /*
     
    818862     */
    819863    RTTIMERLR hTimerLR;
    820     vrc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, teleporterTimeout, hServer);
     864    vrc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, teleporterDstTimeout, hServer);
    821865    if (RT_SUCCESS(vrc))
    822866    {
     
    827871             * Do the job, when it returns we're done.
    828872             */
    829             TeleporterStateTrg State(this, pVM, pMachine, &hTimerLR);
     873            TeleporterStateTrg State(this, pVM, pProgress, pMachine, &hTimerLR);
    830874            State.mstrPassword      = strPassword;
    831875            State.mhServer          = hServer;
    832             State.mpvVMCallbackTask = pvVMCallbackTask;
     876
     877            void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(&State));
     878            pProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser);
    833879
    834880            vrc = RTTcpServerListen(hServer, Console::teleporterTrgServeConnection, &State);
     
    846892                LogRel(("Teleporter: RTTcpServerListen -> %Rrc\n", vrc));
    847893            }
     894
     895            pProgress->setCancelCallback(NULL, NULL);
    848896        }
    849897
     
    9541002            void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
    9551003            vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser,
    956                                      Console::stateProgressCallback, pState->mpvVMCallbackTask);
     1004                                     teleporterProgressCallback, pvUser);
    9571005            if (RT_FAILURE(vrc))
    9581006            {
     
    9781026        }
    9791027        /** @todo implement config verification and hardware compatability checks. Or
    980          *        maybe leave part of these to the saved state machinery? */
     1028         *        maybe leave part of these to the saved state machinery?
     1029         * Update: We're doing as much as possible in the first SSM pass. */
    9811030        else if (!strcmp(szCmd, "done"))
    9821031        {
  • trunk/src/VBox/Main/ProgressImpl.cpp

    r23662 r23810  
    6969    // get creation timestamp
    7070    m_ullTimestamp = RTTimeMilliTS();
     71
     72    m_pfnCancelCallback = NULL;
     73    m_pvCancelUserArg = NULL;
    7174
    7275    return S_OK;
     
    509512    return resultCode;
    510513}
     514
     515/**
     516 * Sets the cancellation callback.
     517 *
     518 * @param   pfnCallback     The function to be called upon cancelation.
     519 * @param   pvUser          The callback argument.
     520 */
     521void ProgressBase::setCancelCallback(void (*pfnCallback)(void *), void *pvUser)
     522{
     523    AutoCaller autoCaller(this);
     524    AssertComRCReturnVoid(autoCaller.rc());
     525
     526    AutoWriteLock alock(this);
     527
     528    m_pvCancelUserArg   = pvUser;
     529    m_pfnCancelCallback = pfnCallback;
     530}
     531
    511532
    512533////////////////////////////////////////////////////////////////////////////////
     
    867888                        tr("Operation cannot be canceled"));
    868889
    869     mCanceled = TRUE;
     890    if (!mCanceled)
     891    {
     892        mCanceled = TRUE;
     893        if (m_pfnCancelCallback)
     894            m_pfnCancelCallback(m_pvCancelUserArg);
     895
     896    }
    870897    return S_OK;
    871898}
     
    15661593        return setError (E_FAIL, tr ("Operation cannot be cancelled"));
    15671594
    1568     mCanceled = TRUE;
     1595    if (!mCanceled)
     1596    {
     1597        mCanceled = TRUE;
     1598/** @todo Teleportation: Shouldn't this be propagated to mProgresses? If
     1599 *        powerUp creates passes a combined progress object to the client, I
     1600 *        won't get called back since I'm only getting the powerupProgress ...
     1601 *        Or what? */
     1602        if (m_pfnCancelCallback)
     1603            m_pfnCancelCallback(m_pvCancelUserArg);
     1604
     1605    }
    15691606    return S_OK;
    15701607}
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r23801 r23810  
    523523    HRESULT                     teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL);
    524524    HRESULT                     teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand);
    525     int                         teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, void *pvVMCallbackTask);
     525    int                         teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, Progress *pProgress);
    526526    static DECLCALLBACK(int)    teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser);
    527527    /** @} */
  • trunk/src/VBox/Main/include/ProgressImpl.h

    r23223 r23810  
    8686
    8787    static HRESULT setErrorInfoOnThread (IProgress *aProgress);
     88    void setCancelCallback(void (*pfnCallback)(void *), void *pvUser);
     89
    8890
    8991    // unsafe inline public methods for internal purposes only (ensure there is
     
    107109
    108110    uint64_t m_ullTimestamp;                        // progress object creation timestamp, for ETA computation
     111
     112    void (*m_pfnCancelCallback)(void *);
     113    void *m_pvCancelUserArg;
    109114
    110115    /* The fields below are to be properly initalized by subclasses */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette