VirtualBox

Changeset 18304 in vbox for trunk/src


Ignore:
Timestamp:
Mar 26, 2009 11:27:20 AM (16 years ago)
Author:
vboxsync
Message:

OVF: common implementation for asynchronous disk progress; more progress fixes

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

Legend:

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

    r18301 r18304  
    17111711        try
    17121712        {
    1713             if (!task->progress.isNull())
    1714                 task->progress->setNextOperation(BstrFmt(tr("Importing virtual system %d"), i + 1),
    1715                                                  pAppliance->m->ulWeightPerOperation);
    1716 
    17171713            /* Guest OS type */
    17181714            std::list<VirtualSystemDescriptionEntry*> vsdeOS;
     
    21382134                        }
    21392135
    2140                         // now loop until the asynchronous operation completes and then report its result
    2141                         BOOL fCompleted;
    2142                         BOOL fCanceled;
    2143                         ULONG currentPercent;
    2144                         while (SUCCEEDED(pProgress2->COMGETTER(Completed(&fCompleted))))
    2145                         {
    2146                             rc = task->progress->COMGETTER(Canceled)(&fCanceled);
    2147                             if (FAILED(rc)) throw rc;
    2148                             if (fCanceled)
    2149                             {
    2150                                 pProgress2->Cancel();
    2151                                 break;
    2152                             }
    2153                             else
    2154                             {
    2155                                 rc = pProgress2->COMGETTER(Percent(&currentPercent));
    2156                                 if (FAILED(rc)) throw rc;
    2157                                 if (!task->progress.isNull())
    2158                                     task->progress->setCurrentOperationProgress(currentPercent);
    2159                                 if (fCompleted)
    2160                                     break;
    2161                             }
    2162                             /* Make sure the loop is not too tight */
    2163                             rc = pProgress2->WaitForCompletion(100);
    2164                             if (FAILED(rc)) throw rc;
    2165                         }
    2166                         // report result of asynchronous operation
    2167                         HRESULT vrc;
    2168                         rc = pProgress2->COMGETTER(ResultCode)(&vrc);
    2169                         if (FAILED(rc)) throw rc;
    2170 
    2171                         // if the thread of the progress object has an error, then
    2172                         // retrieve the error info from there, or it'll be lost
    2173                         if (FAILED(vrc))
    2174                         {
    2175                             ProgressErrorInfo info(pProgress2);
    2176                             Utf8Str str(info.getText());
    2177                             const char *pcsz = str.c_str();
    2178                             HRESULT rc2 = setError(vrc,
    2179                                                    pcsz);
    2180                             throw rc2;
    2181                         }
     2136                        // now wait for the background disk operation to complete; this throws HRESULTs on error
     2137                        pAppliance->waitForAsyncProgress(task->progress, pProgress2);
    21822138
    21832139                        if (fSourceHdNeedsClosing)
     
    30322988                                                     pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
    30332989
    3034                 // now loop until the asynchronous operation completes and then report its result
    3035                 BOOL fCompleted;
    3036                 BOOL fCanceled;
    3037                 ULONG currentPercent;
    3038                 while (SUCCEEDED(pProgress2->COMGETTER(Completed(&fCompleted))))
    3039                 {
    3040                     rc = task->progress->COMGETTER(Canceled)(&fCanceled);
    3041                     if (FAILED(rc)) throw rc;
    3042                     if (fCanceled)
    3043                     {
    3044                         pProgress2->Cancel();
    3045                         break;
    3046                     }
    3047                     else
    3048                     {
    3049                         rc = pProgress2->COMGETTER(Percent(&currentPercent));
    3050                         if (FAILED(rc)) throw rc;
    3051                         if (!task->progress.isNull())
    3052                             task->progress->setCurrentOperationProgress(currentPercent);
    3053                         if (fCompleted)
    3054                             break;
    3055                     }
    3056                     /* Make sure the loop is not too tight */
    3057                     rc = pProgress2->WaitForCompletion(100);
    3058                     if (FAILED(rc)) throw rc;
    3059                 }
    3060                 // report result of asynchronous operation
    3061                 HRESULT vrc;
    3062                 rc = pProgress2->COMGETTER(ResultCode)(&vrc);
    3063                 if (FAILED(rc)) throw rc;
    3064 
    3065                 // if the thread of the progress object has an error, then
    3066                 // retrieve the error info from there, or it'll be lost
    3067                 if (FAILED(vrc))
    3068                 {
    3069                     ProgressErrorInfo info(pProgress2);
    3070                     Utf8Str str(info.getText());
    3071                     const char *pcsz = str.c_str();
    3072                     HRESULT rc2 = setError(vrc, pcsz);
    3073                     throw rc2;
    3074                 }
     2990                // now wait for the background disk operation to complete; this throws HRESULTs on error
     2991                pAppliance->waitForAsyncProgress(task->progress, pProgress2);
    30752992            }
    30762993            catch (HRESULT rc3)
    30772994            {
    3078                 // upon error after registereing, close the disk or
     2995                // upon error after registering, close the disk or
    30792996                // it'll stick in the registry forever
    30802997                pTargetDisk->Close();
     
    32303147    pProgress.createObject();
    32313148
    3232     // use one percent for parsing the XML and one percent for each virtual system
    3233     // in the XML; use the rest (e.g. 97%) for the disk images
    3234     ULONG cFixed = 1 + m->virtualSystemDescriptions.size();
    3235     ULONG ulPercentForDisks = 100 - cFixed;
    3236 
    32373149    // weigh the disk images according to their sizes
    32383150    uint32_t ulTotalMB = 0;
     
    32563168    }
    32573169
     3170    ULONG cOperations = 1 + cDisks;     // one op per disk plus 1 for the XML
     3171
    32583172    ULONG ulTotalOperationsWeight;
    32593173    if (ulTotalMB)
    32603174    {
    3261         ulTotalOperationsWeight = ulTotalMB * 100 / ulPercentForDisks;
    3262         m->ulWeightPerOperation = ulTotalOperationsWeight / 100;
     3175        ulTotalOperationsWeight = (ULONG)((double)ulTotalMB * 99 / 100);    // use 99% of the progress for the disks
     3176        m->ulWeightPerOperation = (ULONG)((double)ulTotalMB * 1  / 100);    // use 1% of the progress for the XML
    32633177    }
    32643178    else
    32653179    {
    32663180        // no disks to export:
    3267         ulTotalOperationsWeight = cFixed;
     3181        ulTotalOperationsWeight = 1;
    32683182        m->ulWeightPerOperation = 1;
    32693183    }
    32703184
    3271     Log(("Setting up progress object: ulTotalMB = %d, cFixed = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n",
    3272          ulTotalMB, cFixed, cDisks, cFixed + (ULONG)cDisks, ulTotalOperationsWeight, m->ulWeightPerOperation));
     3185    Log(("Setting up progress object: ulTotalMB = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n",
     3186         ulTotalMB, cDisks, cOperations, ulTotalOperationsWeight, m->ulWeightPerOperation));
    32733187
    32743188    rc = pProgress->init(mVirtualBox, static_cast<IAppliance*>(this),
    32753189                         bstrDescription,
    32763190                         TRUE /* aCancelable */,
    3277                          cFixed + (ULONG)cDisks, // ULONG cOperations,
     3191                         cOperations, // ULONG cOperations,
    32783192                         ulTotalOperationsWeight, // ULONG ulTotalOperationsWeight,
    32793193                         bstrDescription, // CBSTR bstrFirstOperationDescription,
    32803194                         m->ulWeightPerOperation); // ULONG ulFirstOperationWeight,
    32813195    return rc;
     3196}
     3197
     3198/**
     3199 * Called from the import and export background threads to synchronize the second
     3200 * background disk thread's progress object with the current progress object so
     3201 * that the user interface sees progress correctly and that cancel signals are
     3202 * passed on to the second thread.
     3203 * @param pProgressThis Progress object of the current thread.
     3204 * @param pProgressAsync Progress object of asynchronous task running in background.
     3205 */
     3206void Appliance::waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis,
     3207                                     ComPtr<IProgress> &pProgressAsync)
     3208{
     3209    HRESULT rc;
     3210
     3211    // now loop until the asynchronous operation completes and then report its result
     3212    BOOL fCompleted;
     3213    BOOL fCanceled;
     3214    ULONG currentPercent;
     3215    while (SUCCEEDED(pProgressAsync->COMGETTER(Completed(&fCompleted))))
     3216    {
     3217        rc = pProgressThis->COMGETTER(Canceled)(&fCanceled);
     3218        if (FAILED(rc)) throw rc;
     3219        if (fCanceled)
     3220        {
     3221            pProgressAsync->Cancel();
     3222            break;
     3223        }
     3224
     3225        rc = pProgressAsync->COMGETTER(Percent(&currentPercent));
     3226        if (FAILED(rc)) throw rc;
     3227        if (!pProgressThis.isNull())
     3228            pProgressThis->setCurrentOperationProgress(currentPercent);
     3229        if (fCompleted)
     3230            break;
     3231
     3232        /* Make sure the loop is not too tight */
     3233        rc = pProgressAsync->WaitForCompletion(100);
     3234        if (FAILED(rc)) throw rc;
     3235    }
     3236    // report result of asynchronous operation
     3237    HRESULT vrc;
     3238    rc = pProgressAsync->COMGETTER(ResultCode)(&vrc);
     3239    if (FAILED(rc)) throw rc;
     3240
     3241
     3242    // if the thread of the progress object has an error, then
     3243    // retrieve the error info from there, or it'll be lost
     3244    if (FAILED(vrc))
     3245    {
     3246        ProgressErrorInfo info(pProgressAsync);
     3247        Utf8Str str(info.getText());
     3248        const char *pcsz = str.c_str();
     3249        HRESULT rc2 = setError(vrc, pcsz);
     3250        throw rc2;
     3251    }
    32823252}
    32833253
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r18269 r18304  
    9898    HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const;
    9999    HRESULT setUpProgress(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription);
     100    void waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, ComPtr<IProgress> &pProgressAsync);
    100101    void addWarning(const char* aWarning, ...);
    101102
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