VirtualBox

Changeset 88988 in vbox


Ignore:
Timestamp:
May 11, 2021 9:44:14 PM (4 years ago)
Author:
vboxsync
Message:

FE/VBoxHeadless: Borrow (a simplified version of) showProgress from
VBoxManage, use it to wait for progress completion. bugref:8161

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp

    r85488 r88988  
    797797
    798798#endif /* RT_OS_DARWIN */
     799
     800
     801/*
     802 * Simplified version of showProgress() borrowed from VBoxManage.
     803 */
     804HRESULT
     805showProgress(const ComPtr<IProgress> &progress)
     806{
     807    BOOL fCompleted = FALSE;
     808    ULONG ulLastPercent = 0;
     809    ULONG ulCurrentPercent = 0;
     810    HRESULT hrc;
     811
     812    com::Bstr bstrDescription;
     813    hrc = progress->COMGETTER(Description(bstrDescription.asOutParam()));
     814    if (FAILED(hrc))
     815    {
     816        RTStrmPrintf(g_pStdErr, "Failed to get progress description: %Rhrc\n", hrc);
     817        return hrc;
     818    }
     819
     820    RTStrmPrintf(g_pStdErr, "%ls: ", bstrDescription.raw());
     821    RTStrmFlush(g_pStdErr);
     822
     823    hrc = progress->COMGETTER(Completed(&fCompleted));
     824    while (SUCCEEDED(hrc))
     825    {
     826        progress->COMGETTER(Percent(&ulCurrentPercent));
     827
     828        /* did we cross a 10% mark? */
     829        if (ulCurrentPercent / 10  >  ulLastPercent / 10)
     830        {
     831            /* make sure to also print out missed steps */
     832            for (ULONG curVal = (ulLastPercent / 10) * 10 + 10; curVal <= (ulCurrentPercent / 10) * 10; curVal += 10)
     833            {
     834                if (curVal < 100)
     835                {
     836                    RTStrmPrintf(g_pStdErr, "%u%%...", curVal);
     837                    RTStrmFlush(g_pStdErr);
     838                }
     839            }
     840            ulLastPercent = (ulCurrentPercent / 10) * 10;
     841        }
     842
     843        if (fCompleted)
     844            break;
     845
     846        gEventQ->processEventQueue(500);
     847        hrc = progress->COMGETTER(Completed(&fCompleted));
     848    }
     849
     850    /* complete the line. */
     851    LONG iRc = E_FAIL;
     852    hrc = progress->COMGETTER(ResultCode)(&iRc);
     853    if (SUCCEEDED(hrc))
     854    {
     855        if (SUCCEEDED(iRc))
     856            RTStrmPrintf(g_pStdErr, "100%%\n");
     857#if 0
     858        else if (g_fCanceled)
     859            RTStrmPrintf(g_pStdErr, "CANCELED\n");
     860#endif
     861        else
     862        {
     863            RTStrmPrintf(g_pStdErr, "\n");
     864            RTStrmPrintf(g_pStdErr, "Operation failed: %Rhrc\n", iRc);
     865        }
     866        hrc = iRc;
     867    }
     868    else
     869    {
     870        RTStrmPrintf(g_pStdErr, "\n");
     871        RTStrmPrintf(g_pStdErr, "Failed to obtain operation result: %Rhrc\n", hrc);
     872    }
     873    RTStrmFlush(g_pStdErr);
     874    return hrc;
     875}
     876
    799877
    800878/**
     
    13591437            CHECK_ERROR_BREAK(console, PowerUpPaused(progress.asOutParam()));
    13601438
    1361         /*
    1362          * Wait for the result because there can be errors.
    1363          *
    1364          * It's vital to process events while waiting (teleportation deadlocks),
    1365          * so we'll poll for the completion instead of waiting on it.
    1366          */
    1367         for (;;)
    1368         {
    1369             BOOL fCompleted;
    1370             rc = progress->COMGETTER(Completed)(&fCompleted);
    1371             if (FAILED(rc) || fCompleted)
    1372                 break;
    1373 
    1374             /* Process pending events, then wait for new ones. Note, this
    1375              * processes NULL events signalling event loop termination. */
    1376             gEventQ->processEventQueue(0);
    1377             if (!g_fTerminateFE)
    1378                 gEventQ->processEventQueue(500);
    1379         }
    1380 
    1381         if (SUCCEEDED(progress->WaitForCompletion(-1)))
    1382         {
    1383             /* Figure out if the operation completed with a failed status
    1384              * and print the error message. Terminate immediately, and let
    1385              * the cleanup code take care of potentially pending events. */
    1386             LONG progressRc;
    1387             progress->COMGETTER(ResultCode)(&progressRc);
    1388             rc = progressRc;
    1389             if (FAILED(rc))
    1390             {
    1391                 com::ProgressErrorInfo info(progress);
    1392                 if (info.isBasicAvailable())
    1393                 {
    1394                     RTPrintf("Error: failed to start machine. Error message: %ls\n", info.getText().raw());
    1395                 }
    1396                 else
    1397                 {
    1398                     RTPrintf("Error: failed to start machine. No error message available!\n");
    1399                 }
    1400                 break;
    1401             }
     1439        rc = showProgress(progress);
     1440        if (FAILED(rc))
     1441        {
     1442            com::ProgressErrorInfo info(progress);
     1443            if (info.isBasicAvailable())
     1444            {
     1445                RTPrintf("Error: failed to start machine. Error message: %ls\n", info.getText().raw());
     1446            }
     1447            else
     1448            {
     1449                RTPrintf("Error: failed to start machine. No error message available!\n");
     1450            }
     1451            break;
    14021452        }
    14031453
     
    14511501    {
    14521502        consoleListener->getWrapped()->ignorePowerOffEvents(true);
     1503
    14531504        ComPtr<IProgress> pProgress;
    14541505        CHECK_ERROR_BREAK(gConsole, PowerDown(pProgress.asOutParam()));
    1455         CHECK_ERROR_BREAK(pProgress, WaitForCompletion(-1));
    1456         BOOL completed;
    1457         CHECK_ERROR_BREAK(pProgress, COMGETTER(Completed)(&completed));
    1458         ASSERT(completed);
    1459         LONG hrc;
    1460         CHECK_ERROR_BREAK(pProgress, COMGETTER(ResultCode)(&hrc));
    1461         if (FAILED(hrc))
     1506
     1507        rc = showProgress(pProgress);
     1508        if (FAILED(rc))
    14621509        {
    14631510            RTPrintf("VBoxHeadless: ERROR: Failed to power down VM!");
    14641511            com::ErrorInfo info;
    14651512            if (!info.isFullAvailable() && !info.isBasicAvailable())
    1466                 com::GluePrintRCMessage(hrc);
     1513                com::GluePrintRCMessage(rc);
    14671514            else
    1468                 GluePrintErrorInfo(info);
     1515                com::GluePrintErrorInfo(info);
    14691516            break;
    14701517        }
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