VirtualBox

Changeset 37069 in vbox


Ignore:
Timestamp:
May 13, 2011 12:41:38 PM (13 years ago)
Author:
vboxsync
Message:

Main: add waitForAsyncProgressCompletion to IProgress

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r36991 r37069  
    86918691  <interface
    86928692    name="IProgress" extends="$unknown"
    8693     uuid="A163C98F-8635-4AA8-B770-A9941737F3EF"
     8693    uuid="c20238e4-3221-4d3f-8891-81ce92d9f913"
    86948694    wsmap="managed"
    86958695    >
     
    88858885        </desc>
    88868886      </param>
     8887    </method>
     8888
     8889    <method name="waitForAsyncProgressCompletion">
     8890      <desc>
     8891         Waits until the other task is completed (including all
     8892         sub-operations) and forward all changes from the other progress to
     8893         this progress. This means sub-operation number, description, percent
     8894         and so on.
     8895         
     8896         You have to take care on setting up at least the same count on
     8897         sub-operations in this progress object like there are in the other
     8898         progress object.
     8899
     8900         If the other progress object supports cancel and this object gets any
     8901         cancel request (when here enabled as well), it will be forwarded to
     8902         the other progress object.
     8903
     8904         If there is an error in the other progress, this error isn't
     8905         automatically transfered to this progress object. So you have to
     8906         check any operation error within the other progress object, after
     8907         this method returns.
     8908      </desc>
     8909
     8910     <param name="pProgressAsync" type="IProgress" dir="in">
     8911       <desc>
     8912         The progress object of the asynchrony process.
     8913       </desc>
     8914     </param>
    88878915    </method>
    88888916
  • trunk/src/VBox/Main/include/ProgressImpl.h

    r35638 r37069  
    242242    STDMETHOD(WaitForCompletion)(LONG aTimeout);
    243243    STDMETHOD(WaitForOperationCompletion)(ULONG aOperation, LONG aTimeout);
     244    STDMETHOD(WaitForAsyncProgressCompletion)(IProgress *pProgressAsync);
    244245    STDMETHOD(Cancel)();
    245246
  • trunk/src/VBox/Main/src-all/ProgressImpl.cpp

    r35638 r37069  
    914914
    915915    return S_OK;
     916}
     917
     918STDMETHODIMP Progress::WaitForAsyncProgressCompletion(IProgress *pProgressAsync)
     919{
     920    LogFlowThisFuncEnter();
     921
     922    CheckComArgNotNull(pProgressAsync);
     923
     924    AutoCaller autoCaller(this);
     925    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     926
     927    /* Note: we don't lock here, cause we just using public methods. */
     928
     929    HRESULT rc           = S_OK;
     930    BOOL fCancelable     = FALSE;
     931    BOOL fCompleted      = FALSE;
     932    BOOL fCanceled       = FALSE;
     933    ULONG currentPercent = 0;
     934    ULONG cOp            = 0;
     935    /* Is the async process cancelable? */
     936    rc = pProgressAsync->COMGETTER(Cancelable)(&fCancelable);
     937    if (FAILED(rc)) return rc;
     938    /* Loop as long as the sync process isn't completed. */
     939    while (SUCCEEDED(pProgressAsync->COMGETTER(Completed(&fCompleted))))
     940    {
     941        /* We can forward any cancel request to the async process only when
     942         * it is cancelable. */
     943        if (fCancelable)
     944        {
     945            rc = COMGETTER(Canceled)(&fCanceled);
     946            if (FAILED(rc)) return rc;
     947            if (fCanceled)
     948            {
     949                rc = pProgressAsync->Cancel();
     950                if (FAILED(rc)) return rc;
     951            }
     952        }
     953        /* Even if the user canceled the process, we have to wait until the
     954           async task has finished his work (cleanup and such). Otherwise there
     955           will be sync trouble (still wrong state, dead locks, ...) on the
     956           used objects. So just do nothing, but wait for the complete
     957           notification. */
     958        if (!fCanceled)
     959        {
     960            /* Check if the current operation has changed. It is also possible that
     961             * in the meantime more than one async operation was finished. So we
     962             * have to loop as long as we reached the same operation count. */
     963            ULONG curOp;
     964            for(;;)
     965            {
     966                rc = pProgressAsync->COMGETTER(Operation(&curOp));
     967                if (FAILED(rc)) return rc;
     968                if (cOp != curOp)
     969                {
     970                    Bstr bstr;
     971                    ULONG currentWeight;
     972                    rc = pProgressAsync->COMGETTER(OperationDescription(bstr.asOutParam()));
     973                    if (FAILED(rc)) return rc;
     974                    rc = pProgressAsync->COMGETTER(OperationWeight(&currentWeight));
     975                    if (FAILED(rc)) return rc;
     976                    rc = SetNextOperation(bstr.raw(), currentWeight);
     977                    if (FAILED(rc)) return rc;
     978                    ++cOp;
     979                }else
     980                    break;
     981            }
     982
     983            rc = pProgressAsync->COMGETTER(OperationPercent(&currentPercent));
     984            if (FAILED(rc)) return rc;
     985            rc = SetCurrentOperationProgress(currentPercent);
     986            if (FAILED(rc)) return rc;
     987        }
     988        if (fCompleted)
     989            break;
     990
     991        /* Make sure the loop is not too tight */
     992        rc = pProgressAsync->WaitForCompletion(100);
     993        if (FAILED(rc)) return rc;
     994    }
     995
     996    LogFlowThisFuncLeave();
     997
     998    return rc;
    916999}
    9171000
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