VirtualBox

Changeset 55655 in vbox


Ignore:
Timestamp:
May 5, 2015 11:08:12 AM (9 years ago)
Author:
vboxsync
Message:

FE/Qt: Settings dialog: Fixing serialization flaw due to which Main API errors could bring the Save Progress dialog hang.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/settings
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp

    r55515 r55655  
    6565    /* Loading/saving stuff: */
    6666    , m_pSerializeProcess(0)
    67     , m_pSerializeProgress(0)
    6867    , m_fLoaded(false)
    6968    , m_fSaved(false)
     
    123122    /* Prepare process-bar: */
    124123    m_pProcessBar = new QProgressBar;
     124    m_pProcessBar->setMaximum(100);
     125    m_pProcessBar->setMinimum(0);
    125126
    126127    /* Prepare warning-pane: */
     
    157158        m_pSerializeProcess = 0;
    158159    }
    159     if (serializeProgress())
    160     {
    161         delete m_pSerializeProgress;
    162         m_pSerializeProgress = 0;
    163     }
    164160
    165161    /* Recall popup-pane if any: */
     
    223219        m_pSerializeProcess = 0;
    224220    }
    225     if (serializeProgress())
    226     {
    227         delete m_pSerializeProgress;
    228         m_pSerializeProgress = 0;
    229     }
    230221
    231222    /* Mark as loaded: */
     
    241232        m_pSerializeProcess = 0;
    242233    }
    243     if (serializeProgress())
    244     {
    245         delete m_pSerializeProgress;
    246         m_pSerializeProgress = 0;
    247     }
    248234
    249235    /* Mark as saved: */
     
    257243}
    258244
    259 void UISettingsDialog::sltHandlePageProcessed()
    260 {
    261     m_pProcessBar->setValue(m_pProcessBar->value() + 1);
     245void UISettingsDialog::sltHandleProcessProgressChange(int iValue)
     246{
     247    m_pProcessBar->setValue(iValue);
    262248    if (m_pProcessBar->value() == m_pProcessBar->maximum())
    263249    {
     
    281267        /* Configure settings loader: */
    282268        connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutProcessStarted()), this, SLOT(sltHandleProcessStarted()));
    283         connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutPagePostprocessed(int)), this, SLOT(sltHandlePageProcessed()));
     269        connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutProcessProgressChanged(int)), this, SLOT(sltHandleProcessProgressChange(int)));
    284270        connect(m_pSerializeProcess, SIGNAL(sigNotifyAboutProcessFinished()), this, SLOT(sltMarkLoaded()));
     271
    285272        /* Raise current page priority: */
    286273        m_pSerializeProcess->raisePriorityOfPage(m_pSelector->currentId());
     274
    287275        /* Start settings loader: */
    288276        m_pSerializeProcess->start();
    289     }
    290 
    291     /* Upload data finally: */
    292     data = m_pSerializeProcess->data();
     277
     278        /* Upload data finally: */
     279        data = m_pSerializeProcess->data();
     280    }
    293281}
    294282
     
    298286    m_fSaved = false;
    299287
    300     /* Create settings saver: */
    301     QWidget *pDlgParent = windowManager().realParentWindow(window());
    302     m_pSerializeProgress = new UISettingsSerializerProgress(pDlgParent, UISettingsSerializer::Save,
    303                                                             data, m_pSelector->settingPages());
    304     AssertPtrReturnVoid(m_pSerializeProgress);
    305     {
    306         /* Make setting saver the temporary parent for all the sub-dialogs: */
    307         windowManager().registerNewParent(m_pSerializeProgress, pDlgParent);
    308         /* Start settings saver: */
    309         m_pSerializeProgress->exec();
    310     }
    311 
    312     /* Upload data finally: */
    313     data = m_pSerializeProgress->data();
     288    /* Create the 'settings saver': */
     289    QPointer<UISettingsSerializerProgress> pDlgSerializeProgress =
     290        new UISettingsSerializerProgress(this, UISettingsSerializer::Save,
     291                                         data, m_pSelector->settingPages());
     292    AssertPtrReturnVoid(static_cast<UISettingsSerializerProgress*>(pDlgSerializeProgress));
     293    {
     294        /* Make the 'settings saver' temporary parent for all sub-dialogs: */
     295        windowManager().registerNewParent(pDlgSerializeProgress, windowManager().realParentWindow(this));
     296
     297        /* Execute the 'settings saver': */
     298        pDlgSerializeProgress->exec();
     299
     300        /* Any modal dialog can be destroyed in own event-loop
     301         * as a part of application termination procedure..
     302         * We have to check if the dialog still valid. */
     303        if (pDlgSerializeProgress)
     304        {
     305            /* Upload 'settings saver' data: */
     306            data = pDlgSerializeProgress->data();
     307
     308            /* Delete the 'settings saver': */
     309            delete pDlgSerializeProgress;
     310        }
     311    }
    314312}
    315313
     
    364362        /* Add stack-widget page if created: */
    365363        m_pages[cId] = m_pStack->addWidget(pPage);
    366         /* Update process-bar: */
    367         m_pProcessBar->setMinimum(0);
    368         m_pProcessBar->setMaximum(m_pStack->count());
    369364    }
    370365    /* Assign validator if necessary: */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h

    r55513 r55655  
    3434class UISettingsPage;
    3535class UISettingsSerializer;
    36 class UISettingsSerializerProgress;
    3736
    3837/* Using declarations: */
     
    6867    /* Handlers for process bar: */
    6968    void sltHandleProcessStarted();
    70     void sltHandlePageProcessed();
     69    void sltHandleProcessProgressChange(int iValue);
    7170
    7271protected:
     
    7473    /** Returns the serialize process instance. */
    7574    UISettingsSerializer* serializeProcess() const { return m_pSerializeProcess; }
    76     /** Returns the serialize progress instance. */
    77     UISettingsSerializerProgress* serializeProgress() const { return m_pSerializeProgress; }
    7875
    7976    /** Loads the @a data. */
     
    146143    /** Holds the serialize process instance. */
    147144    UISettingsSerializer *m_pSerializeProcess;
    148     /** Holds the serialize progress instance. */
    149     UISettingsSerializerProgress *m_pSerializeProgress;
    150145
    151146    /* Loading/saving stuff: */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsSerializer.cpp

    r55305 r55655  
    8989void UISettingsSerializer::sltHandleProcessedPage(int iPageId)
    9090{
     91    /* Make sure such page present: */
     92    AssertReturnVoid(m_pages.contains(iPageId));
     93
     94    /* Get the page being processed: */
     95    UISettingsPage *pSettingsPage = m_pages.value(iPageId);
     96
    9197    /* If serializer loads settings: */
    9298    if (m_direction == Load)
    9399    {
    94         /* If such page present: */
    95         if (m_pages.contains(iPageId))
    96         {
    97             /* We should fetch internal page cache: */
    98             UISettingsPage *pSettingsPage = m_pages[iPageId];
    99             pSettingsPage->setValidatorBlocked(true);
    100             pSettingsPage->getFromCache();
    101             pSettingsPage->setValidatorBlocked(false);
    102         }
    103     }
    104     /* Notify listeners about page postprocessed: */
    105     emit sigNotifyAboutPagePostprocessed(iPageId);
     100        /* We should fetch internal page cache: */
     101        pSettingsPage->setValidatorBlocked(true);
     102        pSettingsPage->getFromCache();
     103        pSettingsPage->setValidatorBlocked(false);
     104    }
     105
     106    /* Add processed page into corresponding map: */
     107    m_pagesDone.insert(iPageId, pSettingsPage);
     108
     109    /* Notify listeners about process reached n%: */
     110    const int iValue = 100 * m_pagesDone.size() / m_pages.size();
     111    emit sigNotifyAboutProcessProgressChanged(iValue);
    106112}
    107113
     
    122128            pPage->revalidate();
    123129    }
    124     /* Notify listeners about pages postprocessed: */
    125     emit sigNotifyAboutPagesPostprocessed();
     130
     131    /* Notify listeners about process reached 100%: */
     132    emit sigNotifyAboutProcessProgressChanged(100);
    126133}
    127134
     
    232239    {
    233240        /* Install progress handler: */
    234         connect(m_pSerializer, SIGNAL(sigNotifyAboutPagePostprocessed(int)),
    235                 this, SLOT(sltAdvanceProgressValue()));
    236         connect(m_pSerializer, SIGNAL(sigNotifyAboutPagesPostprocessed()),
    237                 this, SLOT(sltAdvanceProgressValue()));
     241        connect(m_pSerializer, SIGNAL(sigNotifyAboutProcessProgressChanged(int)),
     242                this, SLOT(sltHandleProcessProgressChange(int)));
    238243        connect(m_pSerializer, SIGNAL(sigOperationProgressChange(ulong, QString, ulong, ulong)),
    239244                this, SLOT(sltHandleOperationProgressChange(ulong, QString, ulong, ulong)));
     
    286291                    /* Configure progress bar: */
    287292                    m_pBarOperationProgress->setMinimumWidth(300);
    288                     m_pBarOperationProgress->setMaximum(m_pSerializer->pageCount() + 1);
     293                    m_pBarOperationProgress->setMaximum(100);
    289294                    m_pBarOperationProgress->setMinimum(0);
    290295                    m_pBarOperationProgress->setValue(0);
    291                     connect(m_pBarOperationProgress, SIGNAL(valueChanged(int)),
    292                             this, SLOT(sltProgressValueChanged(int)));
    293296                    /* Add bar into layout: */
    294297                    pLayoutProgress->addWidget(m_pBarOperationProgress);
     
    356359}
    357360
    358 void UISettingsSerializerProgress::sltAdvanceProgressValue()
    359 {
    360     /* Advance the operation progress bar: */
     361void UISettingsSerializerProgress::sltHandleProcessProgressChange(int iValue)
     362{
     363    /* Update the operation progress-bar with incoming value: */
    361364    AssertPtrReturnVoid(m_pBarOperationProgress);
    362     m_pBarOperationProgress->setValue(m_pBarOperationProgress->value() + 1);
    363 }
    364 
    365 void UISettingsSerializerProgress::sltProgressValueChanged(int iValue)
    366 {
     365    m_pBarOperationProgress->setValue(iValue);
    367366    /* Hide the progress-dialog upon reaching the 100% progress: */
    368     AssertPtrReturnVoid(m_pBarOperationProgress);
    369367    if (iValue == m_pBarOperationProgress->maximum())
    370368        hide();
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsSerializer.h

    r55401 r55655  
    4949signals:
    5050
    51     /** Notifies GUI thread about process has been started. */
     51    /** Notifies listeners about process has been started. */
    5252    void sigNotifyAboutProcessStarted();
     53    /** Notifies listeners about process reached @a iValue. */
     54    void sigNotifyAboutProcessProgressChanged(int iValue);
     55    /** Notifies listeners about process has been finished. */
     56    void sigNotifyAboutProcessFinished();
    5357
    5458    /** Notifies GUI thread about some page was processed. */
     
    5660    /** Notifies GUI thread about all pages were processed. */
    5761    void sigNotifyAboutPagesProcessed();
    58 
    59     /** Notifies listeners about some page was post-processed. */
    60     void sigNotifyAboutPagePostprocessed(int iPageId);
    61     /** Notifies listeners about all pages were post-processed. */
    62     void sigNotifyAboutPagesPostprocessed();
    63 
    64     /** Notifies listeners about process has been finished. */
    65     void sigNotifyAboutProcessFinished();
    6662
    6763    /** Notifies listeners about particular operation progress change.
     
    130126    /** Holds the page(s) to load/save the data to/from. */
    131127    UISettingsPageMap m_pages;
     128    /** Holds the page(s) to load/save the data to/from for which that task was done. */
     129    UISettingsPageMap m_pagesDone;
    132130
    133131    /** Holds whether the save was complete. */
     
    187185    void sltStartProcess();
    188186
    189     /** Advances the current progress value. */
    190     void sltAdvanceProgressValue();
    191 
    192     /** Handles the progress value change. */
    193     void sltProgressValueChanged(int iValue);
     187    /** Handles process progress change to @a iValue. */
     188    void sltHandleProcessProgressChange(int iValue);
    194189
    195190    /** Handles particular operation progress change.
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