From bb687bdc455921aafab384f2b2fb79cca6764dcf Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sun, 20 Oct 2013 23:36:53 +0200 Subject: [PATCH] Some improvements in Splash Screen (application initialization) code. --- doc/Changelog.html | 1 + src/Config.h | 2 +- src/Dialog_SplashScreen.cpp | 45 +++++++++++++++++++++------------------------ 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/doc/Changelog.html b/doc/Changelog.html index 3eea5d95..222e98e8 100644 --- a/doc/Changelog.html +++ b/doc/Changelog.html @@ -21,6 +21,7 @@ a:visited { color: #0000EE; }
  • Upgraded build environment to Microsoft Visual Studio 2013 RTM
  • Improved internal encoder API, so each encoder can define its own configuration options
  • Complete overhaul of the file analyzer, resulting in up to 2.5x faster file import speed +
  • Reworked the application initialization code, resulting in somehwat faster startup speed
  • Updated mpg123 decoder to v1.16.0 (2013-10-06), compiled with GCC 4.8.1
  • Updated GnuPG to v1.4.15 (2013-10-05), compiled with GCC 4.8.1
  • Various bugfixes and code improvements diff --git a/src/Config.h b/src/Config.h index 5b21da28..e2c18079 100644 --- a/src/Config.h +++ b/src/Config.h @@ -34,7 +34,7 @@ #define VER_LAMEXP_MINOR_LO 9 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 3 -#define VER_LAMEXP_BUILD 1407 +#define VER_LAMEXP_BUILD 1410 #define VER_LAMEXP_CONFG 1348 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Dialog_SplashScreen.cpp b/src/Dialog_SplashScreen.cpp index 6c361d0b..169478dd 100644 --- a/src/Dialog_SplashScreen.cpp +++ b/src/Dialog_SplashScreen.cpp @@ -34,9 +34,8 @@ #define OPACITY_DELTA 0.02 /* It can happen that the QThread has just terminated and already emitted the 'terminated' signal, but did NOT change the 'isRunning' flag to FALSE yet. */ -/* For this reason the macro will first check the 'isRunning' flag. If (and only if) the flag still returns TRUE, then we will wait() for at most 50 ms. */ -/* If, after 50 ms, the wait() function returns with FALSE, then the thread probably is still running and we return TRUE. Otherwise we can return FALSE. */ -#define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(50))) : false) +/* For this reason the macro will first check the 'isRunning' flag. If (and only if) the flag still returns TRUE, we will call the wait() on the thread. */ +#define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(1))) : false) #define SET_TASKBAR_STATE(FLAG) do \ { \ @@ -51,6 +50,13 @@ } \ while(0) +#define ASYNC_WAIT(LOOP, DELAY) do \ +{ \ + QTimer::singleShot((DELAY), (LOOP), SLOT(quit())); \ + (LOOP)->exec(QEventLoop::ExcludeUserInputEvents); \ +} \ +while(0) + //////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////// @@ -94,14 +100,14 @@ SplashScreen::~SplashScreen(void) void SplashScreen::showSplash(QThread *thread) { - double opacity = OPACITY_DELTA; const int opacitySteps = qRound(1.0 / OPACITY_DELTA); - SplashScreen *splashScreen = new SplashScreen(); bool bTaskBar = false; + unsigned int deadlockCounter = 0; + SplashScreen *splashScreen = new SplashScreen(); //Show splash splashScreen->m_canClose = false; - splashScreen->setWindowOpacity(opacity); + splashScreen->setWindowOpacity(OPACITY_DELTA); splashScreen->setFixedSize(splashScreen->size()); splashScreen->show(); @@ -119,10 +125,8 @@ void SplashScreen::showSplash(QThread *thread) QTimer *timer = new QTimer(); connect(timer, SIGNAL(timeout()), loop, SLOT(quit())); - //Start thread - QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + //Start the thread thread->start(); - QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); //Init taskbar SET_TASKBAR_STATE(true); @@ -130,29 +134,23 @@ void SplashScreen::showSplash(QThread *thread) //Fade in for(int i = 1; i <= opacitySteps; i++) { - opacity = (i < opacitySteps) ? (OPACITY_DELTA * static_cast(i)) : 1.0; + const double opacity = (i < opacitySteps) ? (OPACITY_DELTA * static_cast(i)) : 1.0; splashScreen->setWindowOpacity(opacity); splashScreen->update(); - QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY); + ASYNC_WAIT(loop, FADE_DELAY); SET_TASKBAR_STATE(true); - lamexp_sleep(FADE_DELAY); } //Start the timer timer->start(30720); //Loop while thread is still running - if(bool bIsRunning = THREAD_RUNNING(thread)) + while(THREAD_RUNNING(thread)) { - int deadlockCounter = 0; - while(bIsRunning) + ASYNC_WAIT(loop, 500); + if((deadlockCounter++ > 360) && thread->isRunning()) { - loop->exec(); - if(bIsRunning = THREAD_RUNNING(thread)) - { - qWarning("Potential deadlock in initialization thread!"); - if(++deadlockCounter >= 10) qFatal("Deadlock in initialization thread!"); - } + qFatal("Deadlock in initialization thread detected!"); } } @@ -162,11 +160,10 @@ void SplashScreen::showSplash(QThread *thread) //Fade out for(int i = opacitySteps; i >= 0; i--) { - opacity = OPACITY_DELTA * static_cast(i); + const double opacity = OPACITY_DELTA * static_cast(i); splashScreen->setWindowOpacity(opacity); splashScreen->update(); - QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY); - lamexp_sleep(FADE_DELAY); + ASYNC_WAIT(loop, FADE_DELAY); } //Restore taskbar -- 2.11.0