VirtualBox

Ignore:
Timestamp:
Jun 1, 2010 6:39:21 AM (15 years ago)
Author:
vboxsync
Message:

reverted r62200 as it breaks powerup

File:
1 edited

Legend:

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

    r29932 r29934  
    4646HRESULT ProgressProxy::FinalConstruct()
    4747{
    48     mfMultiOperation = false;
    49     muOtherProgressStartWeight = 0;
    50     muOtherProgressWeight = 0;
    51     muOtherProgressStartOperation = 0;
     48    mcOtherProgressObjects = 1;
     49    miCurOtherProgressObject = 0;
    5250
    5351    HRESULT rc = Progress::FinalConstruct();
     
    6866                            BOOL fCancelable)
    6967{
    70     mfMultiOperation = false;
    71     muOtherProgressStartWeight = 1;
    72     muOtherProgressWeight = 1;
    73     muOtherProgressStartOperation = 1;
     68    miCurOtherProgressObject = 0;
     69    mcOtherProgressObjects = 0;
    7470
    7571    return Progress::init(
     
    8884
    8985/**
    90  * Initialize for proxying one other progress object.
    91  *
    92  * This is tailored explicitly for the openRemoteSession code, so we start out
    93  * with one operation where we don't have any remote object (powerUp).  Then a
    94  * remote object is added and stays with us till the end.
    95  *
    96  * The user must do normal completion notification or risk leave the threads
    97  * waiting forever!
     86 * Initialize for proxying one or more other objects, assuming we start out and
     87 * end without proxying anyone.
     88 *
     89 * The user must call clearOtherProgressObject when there are no more progress
     90 * objects to be proxied or we'll leave threads waiting forever.
    9891 */
    9992HRESULT ProgressProxy::init(
     
    10497                            CBSTR bstrDescription,
    10598                            BOOL fCancelable,
     99                            ULONG cOtherProgressObjects,
    106100                            ULONG uTotalOperationsWeight,
    107101                            CBSTR bstrFirstOperationDescription,
    108102                            ULONG uFirstOperationWeight,
    109                             ULONG cOtherProgressObjectOperations)
    110 {
    111     mfMultiOperation = false;
    112     muOtherProgressStartWeight    = uFirstOperationWeight;
    113     muOtherProgressWeight         = uTotalOperationsWeight - uFirstOperationWeight;
    114     muOtherProgressStartOperation = 1;
     103                            OUT_GUID pId)
     104{
     105    miCurOtherProgressObject = 0;
     106    mcOtherProgressObjects = cOtherProgressObjects;
    115107
    116108    return Progress::init(
     
    121113                          bstrDescription,
    122114                          fCancelable,
    123                           1 + cOtherProgressObjectOperations /* cOperations */,
     115                          1 + cOtherProgressObjects + 1 /* cOperations */,
    124116                          uTotalOperationsWeight,
    125117                          bstrFirstOperationDescription,
    126118                          uFirstOperationWeight,
    127                           NULL);
     119                          pId);
    128120}
    129121
     
    131123{
    132124    uninit();
    133     mfMultiOperation = false;
    134     muOtherProgressStartWeight    = 0;
    135     muOtherProgressWeight         = 0;
    136     muOtherProgressStartOperation = 0;
     125    miCurOtherProgressObject = 0;
    137126}
    138127
     
    186175/** Just a wrapper so we can automatically do the handover before setting
    187176 *  the result locally. */
    188 bool ProgressProxy::notifyPointOfNoReturn(void)
     177bool    ProgressProxy::notifyPointOfNoReturn(void)
    189178{
    190179    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    199188 * @returns false if failed/canceled, true if not.
    200189 * @param   pOtherProgress      The other progress object. Must not be NULL.
    201  */
    202 bool ProgressProxy::setOtherProgressObject(IProgress *pOtherProgress)
    203 {
    204     LogFlowThisFunc(("setOtherProgressObject: %p\n", pOtherProgress));
     190 * @param   uOperationWeight    The weight of this operation.  (The description
     191 *                              is taken from the other progress object.)
     192 */
     193bool ProgressProxy::setOtherProgressObject(IProgress *pOtherProgress, ULONG uOperationWeight)
     194{
     195    LogFlowThisFunc(("setOtherProgressObject: %p %u\n", pOtherProgress, uOperationWeight));
    205196    ComPtr<IProgress> ptrOtherProgress = pOtherProgress;
    206197
    207     /*
    208      * Query information from the other progress object before we grab the
    209      * lock.
    210      */
    211     ULONG cOperations;
    212     HRESULT hrc = pOtherProgress->COMGETTER(OperationCount)(&cOperations);
    213     if (FAILED(hrc))
    214         cOperations = 1;
    215 
    216     Bstr bstrOperationDescription;
    217     hrc = pOtherProgress->COMGETTER(Description)(bstrOperationDescription.asOutParam());
     198    /* Get the description first. */
     199    Bstr    bstrOperationDescription;
     200    HRESULT hrc = pOtherProgress->COMGETTER(Description)(bstrOperationDescription.asOutParam());
    218201    if (FAILED(hrc))
    219202        bstrOperationDescription = "oops";
    220203
    221 
    222     /*
    223      * Take the lock and check for cancelation, cancel the other object if
    224      * we've been canceled already.
    225      */
    226204    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    227205
     206    /* Do the hand over from any previous progress object. */
     207    clearOtherProgressObjectInternal(false /*fEarly*/);
    228208    BOOL fCompletedOrCanceled = mCompleted || mCanceled;
    229209    if (!fCompletedOrCanceled)
    230210    {
    231         /*
    232          * Advance to the next object and operation. If the other object has
    233          * more operations than anticipated, adjust our internal count.
    234          */
     211        /* Advance to the next object and operation, checking for cancelation
     212           and completion right away to be on the safe side. */
     213        Assert(miCurOtherProgressObject < mcOtherProgressObjects);
    235214        mptrOtherProgress = ptrOtherProgress;
    236         mfMultiOperation  = cOperations > 1;
    237 
    238         muOtherProgressStartWeight = m_ulOperationsCompletedWeight + m_ulCurrentOperationWeight;
    239         muOtherProgressWeight      = m_ulTotalOperationsWeight - muOtherProgressStartWeight;
    240         Progress::SetNextOperation(bstrOperationDescription, muOtherProgressWeight);
    241 
    242         muOtherProgressStartOperation = m_ulCurrentOperation;
    243         m_cOperations = cOperations + m_ulCurrentOperation;
    244 
    245         /*
    246          * Check for cancelation and completion.
    247          */
     215
     216        Progress::SetNextOperation(bstrOperationDescription, uOperationWeight);
     217
    248218        BOOL f;
    249219        hrc = ptrOtherProgress->COMGETTER(Completed)(&f);
     
    263233        else
    264234        {
    265             /*
    266              * Finally, mirror the cancelable property.
    267              * Note! Note necessary if we do passthru!
    268              */
     235            /* Mirror the cancelable property. */
    269236            if (mCancelable)
    270237            {
     
    290257}
    291258
     259/**
     260 * Clears the last other progress objects.
     261 *
     262 * @returns false if failed/canceled, true if not.
     263 * @param   pszLastOperationDescription     The description of the final bit.
     264 * @param   uLastOperationWeight            The weight of the final bit.
     265 */
     266bool ProgressProxy::clearOtherProgressObject(const char *pszLastOperationDescription, ULONG uLastOperationWeight)
     267{
     268    LogFlowThisFunc(("%p %u\n", pszLastOperationDescription, uLastOperationWeight));
     269    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     270
     271    clearOtherProgressObjectInternal(false /* fEarly */);
     272
     273    /* Advance to the next operation if applicable. */
     274    bool fCompletedOrCanceled = mCompleted || mCanceled;
     275    if (!fCompletedOrCanceled)
     276        Progress::SetNextOperation(Bstr(pszLastOperationDescription), uLastOperationWeight);
     277
     278    LogFlowThisFunc(("Returns %RTbool\n", !fCompletedOrCanceled));
     279    return !fCompletedOrCanceled;
     280}
     281
    292282// Internal methods.
    293283////////////////////////////////////////////////////////////////////////////////
     
    295285
    296286/**
    297  * Clear the other progress object reference, first copying over its state.
    298  *
    299  * This is used internally when completion is signalled one way or another.
     287 * Internal version of clearOtherProgressObject that doesn't advance to the next
     288 * operation.
     289 *
     290 * This is used both by clearOtherProgressObject as well as a number of places
     291 * where we automatically do the hand over because of failure/completion.
    300292 *
    301293 * @param   fEarly          Early clearing or not.
     
    303295void ProgressProxy::clearOtherProgressObjectInternal(bool fEarly)
    304296{
    305     if (mptrOtherProgress.isNotNull())
     297    if (!mptrOtherProgress.isNull())
    306298    {
    307299        ComPtr<IProgress> ptrOtherProgress = mptrOtherProgress;
    308300        mptrOtherProgress.setNull();
    309301        copyProgressInfo(ptrOtherProgress, fEarly);
     302
     303        miCurOtherProgressObject++;
     304        Assert(miCurOtherProgressObject <= mcOtherProgressObjects);
    310305    }
    311306}
     
    418413////////////////////////////////////////////////////////////////////////////////
    419414
    420 STDMETHODIMP ProgressProxy::COMGETTER(Cancelable)(BOOL *aCancelable)
    421 {
    422     CheckComArgOutPointerValid(aCancelable);
     415STDMETHODIMP ProgressProxy::COMGETTER(Percent)(ULONG *aPercent)
     416{
     417#if 0
     418    CheckComArgOutPointerValid(aPercent);
    423419
    424420    AutoCaller autoCaller(this);
    425421    HRESULT hrc = autoCaller.rc();
    426     if (SUCCEEDED(hrc))
     422    if (SUCCEEDED(rc))
    427423    {
    428424        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    429425
    430         /* ASSUME: The cancelable property can only change to FALSE. */
    431         if (!mCancelable || mptrOtherProgress.isNull())
    432             *aCancelable = mCancelable;
    433         else
    434         {
    435             hrc = mptrOtherProgress->COMGETTER(Cancelable)(aCancelable);
    436             if (SUCCEEDED(hrc) && !*aCancelable)
    437             {
    438                 LogFlowThisFunc(("point-of-no-return reached\n"));
    439                 mCancelable = FALSE;
    440             }
    441         }
    442     }
    443     return hrc;
    444 }
    445 
    446 STDMETHODIMP ProgressProxy::COMGETTER(Percent)(ULONG *aPercent)
    447 {
    448     CheckComArgOutPointerValid(aPercent);
    449 
    450     AutoCaller autoCaller(this);
    451     HRESULT hrc = autoCaller.rc();
    452     if (SUCCEEDED(hrc))
    453     {
    454         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    455 
    456         if (mptrOtherProgress.isNotNull())
     426        if (mptrOtherProgress.isNull())
    457427            hrc = Progress::COMGETTER(Percent)(aPercent);
    458428        else
    459429        {
    460             /*
    461              * Get the overall percent of the other object and adjust it with
    462              * the weighting given to the period before proxying started.
    463              */
    464430            ULONG uPct;
    465431            hrc = mptrOtherProgress->COMGETTER(Percent)(&uPct);
    466             if (SUCCEEDED(hrc))
    467             {
    468                 double rdPercent = ((double)uPct / 100 * muOtherProgressWeight + muOtherProgressStartWeight)
    469                                  / m_ulTotalOperationsWeight * 100;
    470                 *aPercent = RT_MIN((ULONG)rdPercent, 99); /* mptrOtherProgress is cleared when its completed, so we can never return 100%. */
    471             }
     432            ....
    472433        }
    473434    }
    474435    return hrc;
    475 }
    476 
    477 STDMETHODIMP ProgressProxy::COMGETTER(TimeRemaining)(LONG *aTimeRemaining)
    478 {
    479     CheckComArgOutPointerValid(aTimeRemaining);
    480 
    481     AutoCaller autoCaller(this);
    482     HRESULT hrc = autoCaller.rc();
    483     if (SUCCEEDED(hrc))
    484     {
    485         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    486 
    487         if (mptrOtherProgress.isNotNull())
    488             hrc = Progress::COMGETTER(TimeRemaining)(aTimeRemaining);
    489         else
    490             hrc = mptrOtherProgress->COMGETTER(TimeRemaining)(aTimeRemaining);
    491     }
    492     return hrc;
     436#else
     437    return Progress::COMGETTER(Percent)(aPercent);
     438#endif
    493439}
    494440
    495441STDMETHODIMP ProgressProxy::COMGETTER(Completed)(BOOL *aCompleted)
    496442{
    497     /* Not proxied since we EXPECT a normal completion notification call. */
     443    /* Not proxied since we EXPECT a hand back call. */
    498444    return Progress::COMGETTER(Completed)(aCompleted);
    499445}
     
    512458        if (   SUCCEEDED(hrc)
    513459            && !*aCanceled
    514             && mptrOtherProgress.isNotNull()
    515             && mCancelable)
     460            && !mptrOtherProgress.isNull())
    516461        {
    517462            hrc = mptrOtherProgress->COMGETTER(Canceled)(aCanceled);
    518463            if (SUCCEEDED(hrc) && *aCanceled)
    519                 /* This will not complete the object, only mark it as canceled. */
    520                 clearOtherProgressObjectInternal(false /*fEarly*/);
     464                clearOtherProgressObjectInternal(true /*fEarly*/);
    521465        }
    522466    }
     
    526470STDMETHODIMP ProgressProxy::COMGETTER(ResultCode)(LONG *aResultCode)
    527471{
    528     /* Not proxied since we EXPECT a normal completion notification call. */
     472    /* Not proxied yet since we EXPECT a hand back call. */
    529473    return Progress::COMGETTER(ResultCode)(aResultCode);
    530474}
     
    532476STDMETHODIMP ProgressProxy::COMGETTER(ErrorInfo)(IVirtualBoxErrorInfo **aErrorInfo)
    533477{
    534     /* Not proxied since we EXPECT a normal completion notification call. */
     478    /* Not proxied yet since we EXPECT a hand back call. */
    535479    return Progress::COMGETTER(ErrorInfo)(aErrorInfo);
    536480}
    537481
    538 STDMETHODIMP ProgressProxy::COMGETTER(Operation)(ULONG *aOperation)
    539 {
    540     CheckComArgOutPointerValid(aOperation);
    541 
    542     AutoCaller autoCaller(this);
    543     HRESULT hrc = autoCaller.rc();
    544     if (SUCCEEDED(hrc))
    545     {
    546         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    547         if (mptrOtherProgress.isNull())
    548             hrc =  Progress::COMGETTER(Operation)(aOperation);
    549         else
    550         {
    551             ULONG uCurOtherOperation;
    552             hrc = mptrOtherProgress->COMGETTER(Operation)(&uCurOtherOperation);
    553             if (SUCCEEDED(hrc))
    554                 *aOperation = uCurOtherOperation + muOtherProgressStartOperation;
    555         }
    556     }
    557     return hrc;
    558 }
    559 
    560 STDMETHODIMP ProgressProxy::COMGETTER(OperationDescription)(BSTR *aOperationDescription)
    561 {
    562     CheckComArgOutPointerValid(aOperationDescription);
    563 
    564     AutoCaller autoCaller(this);
    565     HRESULT hrc = autoCaller.rc();
    566     if (SUCCEEDED(hrc))
    567     {
    568         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    569         if (mptrOtherProgress.isNull() || !mfMultiOperation)
    570             hrc = Progress::COMGETTER(OperationDescription)(aOperationDescription);
    571         else
    572             hrc = mptrOtherProgress->COMGETTER(OperationDescription)(aOperationDescription);
    573     }
    574     return hrc;
    575 }
    576 
    577482STDMETHODIMP ProgressProxy::COMGETTER(OperationPercent)(ULONG *aOperationPercent)
    578483{
    579     CheckComArgOutPointerValid(aOperationPercent);
    580 
    581     AutoCaller autoCaller(this);
    582     HRESULT hrc = autoCaller.rc();
    583     if (SUCCEEDED(hrc))
    584     {
    585         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    586         if (mptrOtherProgress.isNull() || !mfMultiOperation)
    587             hrc = Progress::COMGETTER(OperationPercent)(aOperationPercent);
    588         else
    589             hrc = mptrOtherProgress->COMGETTER(OperationPercent)(aOperationPercent);
    590     }
    591     return hrc;
     484    /* Not proxied, should be proxied later on. */
     485    return Progress::COMGETTER(OperationPercent)(aOperationPercent);
    592486}
    593487
     
    618512    LogFlowThisFunc(("aTimeout=%d\n", aTimeout));
    619513
    620     /* No need to wait on the proxied object for these since we'll get the
    621        normal completion notifications. */
     514    /* For now we'll always block locally. */
    622515    hrc = Progress::WaitForCompletion(aTimeout);
    623516
     
    628521STDMETHODIMP ProgressProxy::WaitForOperationCompletion(ULONG aOperation, LONG aTimeout)
    629522{
     523    HRESULT hrc;
    630524    LogFlowThisFuncEnter();
    631525    LogFlowThisFunc(("aOperation=%d aTimeout=%d\n", aOperation, aTimeout));
    632526
    633     AutoCaller autoCaller(this);
    634     HRESULT hrc = autoCaller.rc();
    635     if (SUCCEEDED(hrc))
    636     {
    637         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    638 
    639         CheckComArgExpr(aOperation, aOperation < m_cOperations);
    640 
    641         /*
    642          * Check if we can wait locally.
    643          */
    644         if (   aOperation + 1 == m_cOperations /* final operation */
    645             || mptrOtherProgress.isNull())
    646         {
    647             /* ASSUMES that Progress::WaitForOperationCompletion is using
    648                AutoWriteLock::leave() as it saves us from duplicating the code! */
    649             hrc = Progress::WaitForOperationCompletion(aOperation, aTimeout);
    650         }
    651         else
    652         {
    653             LogFlowThisFunc(("calling the other object...\n"));
    654             ComPtr<IProgress> ptrOtherProgress = mptrOtherProgress;
    655             alock.release();
    656 
    657             hrc = ptrOtherProgress->WaitForOperationCompletion(aOperation, aTimeout);
    658         }
    659     }
     527    /* For now we'll always block locally. Later though, we could consider
     528       blocking remotely when we can. */
     529    hrc = Progress::WaitForOperationCompletion(aOperation, aTimeout);
    660530
    661531    LogFlowThisFuncLeave();
     
    671541    {
    672542        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    673         if (mptrOtherProgress.isNull() || !mCancelable)
    674             hrc = Progress::Cancel();
     543        if (mCancelable)
     544        {
     545            if (!mptrOtherProgress.isNull())
     546            {
     547                hrc = mptrOtherProgress->Cancel();
     548                if (SUCCEEDED(hrc))
     549                {
     550                    if (m_pfnCancelCallback)
     551                        m_pfnCancelCallback(m_pvCancelUserArg);
     552                    clearOtherProgressObjectInternal(true /*fEarly*/);
     553                }
     554            }
     555            else
     556                hrc = Progress::Cancel();
     557        }
    675558        else
    676         {
    677             hrc = mptrOtherProgress->Cancel();
    678             if (SUCCEEDED(hrc))
    679                 clearOtherProgressObjectInternal(false /*fEarly*/);
    680         }
     559            hrc = setError(E_FAIL, tr("Operation cannot be canceled"));
    681560    }
    682561
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