diff options
Diffstat (limited to 'vcl/source/app/scheduler.cxx')
-rw-r--r-- | vcl/source/app/scheduler.cxx | 217 |
1 files changed, 102 insertions, 115 deletions
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index 49838c92f993..c3cea781e6b8 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -21,88 +21,85 @@ #include <tools/time.hxx> #include <vcl/scheduler.hxx> #include <vcl/timer.hxx> -#include <algorithm> #include <saltimer.hxx> -void Scheduler::ImplInvoke(sal_uInt64 nTime) -{ - mnUpdateTime = nTime; +#define MAX_TIMER_PERIOD SAL_MAX_UINT64 - if (mpSchedulerData->mbDelete || mbInScheduler ) +void ImplSchedulerData::Invoke() +{ + if (mbDelete || mbInScheduler ) return; // prepare Scheduler Object for deletion after handling - SetDeletionFlags(); + mpScheduler->SetDeletionFlags(); // invoke it mbInScheduler = true; - Invoke(); + mpScheduler->Invoke(); mbInScheduler = false; } -Scheduler* Scheduler::ImplGetHighestPrioTask( bool bTimer ) +ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimer ) { - ImplSVData* pSVData = ImplGetSVData(); - Scheduler * pMostUrgent = NULL; + ImplSVData* pSVData = ImplGetSVData(); + ImplSchedulerData *pMostUrgent = NULL; - std::for_each(pSVData->maSchedulers->begin(), pSVData->maSchedulers->end(), - [&pSVData, bTimer, &pMostUrgent] (ImplSchedulerData *rScheduler) + for ( ImplSchedulerData *pSchedulerData = pSVData->mpFirstSchedulerData; pSchedulerData; pSchedulerData = pSchedulerData->mpNext ) { - if ( rScheduler->mpScheduler && - rScheduler->mpScheduler->ImplIsScheduleReady(pSVData->mnUpdateStack) && - rScheduler->mpScheduler->ReadyForSchedule( bTimer ) && - rScheduler->mpScheduler->IsActive() ) + if ( !pSchedulerData->mpScheduler || pSchedulerData->mbDelete || pSchedulerData->mnUpdateStack >= pSVData->mnUpdateStack + || !pSchedulerData->mpScheduler->ReadyForSchedule( bTimer ) || !pSchedulerData->mpScheduler->IsActive()) + continue; + if (!pMostUrgent) + pMostUrgent = pSchedulerData; + else { - if (!pMostUrgent) - pMostUrgent = rScheduler->mpScheduler; - else - { - // Find the highest priority. - // If the priority of the current task is higher (numerical value is lower) than - // the priority of the most urgent, the current task gets the new most urgent. - if ( rScheduler->mpScheduler->GetPriority() < pMostUrgent->GetPriority() ) - pMostUrgent = rScheduler->mpScheduler; - } + // Find the highest priority. + // If the priority of the current task is higher (numerical value is lower) than + // the priority of the most urgent, the current task gets the new most urgent. + if ( pSchedulerData->mpScheduler->GetPriority() < pMostUrgent->mpScheduler->GetPriority() ) + pMostUrgent = pSchedulerData; } - }); + } return pMostUrgent; } void Scheduler::SetDeletionFlags() { - Stop(); + mpSchedulerData->mbDelete = true; + mbActive = false; } -void Scheduler::ImplDeInitScheduler(bool bAll /*=true*/) +void Scheduler::ImplDeInitScheduler() { - ImplSVData* pSVData = ImplGetSVData(); - + ImplSVData* pSVData = ImplGetSVData(); + ImplSchedulerData* pSchedulerData = pSVData->mpFirstSchedulerData; if (pSVData->mpSalTimer) { pSVData->mpSalTimer->Stop(); } - pSVData->maSchedulers->remove_if( [] (ImplSchedulerData *rSchedulerData) + if ( pSchedulerData ) { - if(rSchedulerData->mpScheduler != NULL) + do { - rSchedulerData->mpScheduler->ImplDispose(); + ImplSchedulerData* pTempSchedulerData = pSchedulerData; + if ( pSchedulerData->mpScheduler ) + { + pSchedulerData->mpScheduler->mbActive = false; + pSchedulerData->mpScheduler->mpSchedulerData = NULL; + } + pSchedulerData = pSchedulerData->mpNext; + delete pTempSchedulerData; } - else - delete rSchedulerData; - - return true; - }); + while ( pSchedulerData ); - if(bAll) - { - delete pSVData->maSchedulers; - pSVData->maSchedulers = NULL; + pSVData->mpFirstSchedulerData = NULL; + pSVData->mnTimerPeriod = 0; } delete pSVData->mpSalTimer; - pSVData->mpSalTimer = NULL; + pSVData->mpSalTimer = 0; } void Scheduler::CallbackTaskScheduling(bool ignore) @@ -116,30 +113,52 @@ void Scheduler::ProcessTaskScheduling( bool bTimer ) { // process all pending Tasks // if bTimer True, only handle timer - Scheduler* pScheduler = NULL; - ImplSVData* pSVData = ImplGetSVData(); - sal_uInt64 nTime = tools::Time::GetSystemTicks(); - sal_uInt64 nMinPeriod = MAX_TIMER_PERIOD; - + ImplSchedulerData* pSchedulerData = NULL; + ImplSchedulerData* pPrevSchedulerData = NULL; + ImplSVData* pSVData = ImplGetSVData(); + sal_uInt64 nTime = tools::Time::GetSystemTicks(); + sal_uInt64 nMinPeriod = MAX_TIMER_PERIOD; pSVData->mnUpdateStack++; // tdf#91727 - NB. bTimer is ultimately not used - if ((pScheduler = Scheduler::ImplGetHighestPrioTask(bTimer)) != NULL) - pScheduler->ImplInvoke(nTime); + if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimer))) + { + pSchedulerData->mnUpdateTime = nTime; + pSchedulerData->Invoke(); + } - pSVData->maSchedulers->remove_if( [&nMinPeriod, nTime, pSVData] (ImplSchedulerData *rSchedulerData) + pSchedulerData = pSVData->mpFirstSchedulerData; + while ( pSchedulerData ) { - if (rSchedulerData->mpScheduler != 0) - return rSchedulerData->mpScheduler->ImplHandleTaskScheduling(nMinPeriod, nTime); + if( pSchedulerData->mbInScheduler ) + { + pPrevSchedulerData = pSchedulerData; + pSchedulerData = pSchedulerData->mpNext; + } + // Should Task be released from scheduling? + else if ( pSchedulerData->mbDelete ) + { + if ( pPrevSchedulerData ) + pPrevSchedulerData->mpNext = pSchedulerData->mpNext; + else + pSVData->mpFirstSchedulerData = pSchedulerData->mpNext; + if ( pSchedulerData->mpScheduler ) + pSchedulerData->mpScheduler->mpSchedulerData = NULL; + ImplSchedulerData* pTempSchedulerData = pSchedulerData; + pSchedulerData = pSchedulerData->mpNext; + delete pTempSchedulerData; + } else { - delete rSchedulerData; - return true; + pSchedulerData->mnUpdateStack = 0; + nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime ); + pPrevSchedulerData = pSchedulerData; + pSchedulerData = pSchedulerData->mpNext; } - }); + } // delete clock if no more timers available - if ( pSVData->maSchedulers->empty() ) + if ( !pSVData->mpFirstSchedulerData ) { if ( pSVData->mpSalTimer ) pSVData->mpSalTimer->Stop(); @@ -149,7 +168,6 @@ void Scheduler::ProcessTaskScheduling( bool bTimer ) { Timer::ImplStartTimer( pSVData, nMinPeriod ); } - pSVData->mnUpdateStack--; } @@ -160,22 +178,34 @@ void Scheduler::SetPriority( SchedulerPriority ePriority ) void Scheduler::Start() { - ImplSVData* pSVData = ImplGetSVData(); // Mark timer active mbActive = true; + ImplSVData* pSVData = ImplGetSVData(); if ( !mpSchedulerData ) { - mpSchedulerData = new ImplSchedulerData; - mpSchedulerData->mpScheduler = this; // insert Scheduler - mbInScheduler = false; - pSVData->maSchedulers->push_back(mpSchedulerData); + mpSchedulerData = new ImplSchedulerData; + mpSchedulerData->mpScheduler = this; + mpSchedulerData->mbInScheduler = false; + + // insert last due to SFX! + ImplSchedulerData* pPrev = NULL; + ImplSchedulerData* pData = pSVData->mpFirstSchedulerData; + while ( pData ) + { + pPrev = pData; + pData = pData->mpNext; + } + mpSchedulerData->mpNext = NULL; + if ( pPrev ) + pPrev->mpNext = mpSchedulerData; + else + pSVData->mpFirstSchedulerData = mpSchedulerData; } - - mpSchedulerData->mbDelete = false; - mnUpdateTime = tools::Time::GetSystemTicks(); - mnUpdateStack = pSVData->mnUpdateStack; + mpSchedulerData->mbDelete = false; + mpSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks(); + mpSchedulerData->mnUpdateStack = pSVData->mnUpdateStack; } void Scheduler::Stop() @@ -191,7 +221,7 @@ Scheduler& Scheduler::operator=( const Scheduler& rScheduler ) if ( IsActive() ) Stop(); - mbActive = false; + mbActive = false; mePriority = rScheduler.mePriority; if ( rScheduler.IsActive() ) @@ -204,17 +234,15 @@ Scheduler::Scheduler(const sal_Char *pDebugName): mpSchedulerData(NULL), mpDebugName(pDebugName), mePriority(SchedulerPriority::HIGH), - mbActive(false), - mnUpdateTime(0) + mbActive(false) { } Scheduler::Scheduler( const Scheduler& rScheduler ): mpSchedulerData(NULL), mpDebugName(rScheduler.mpDebugName), - mePriority(SchedulerPriority::HIGH), - mbActive(false), - mnUpdateTime(0) + mePriority(rScheduler.mePriority), + mbActive(false) { if ( rScheduler.IsActive() ) Start(); @@ -229,44 +257,3 @@ Scheduler::~Scheduler() } } -bool Scheduler::ImplIsScheduleReady(sal_uInt32 nUpdateStack) -{ - return !mpSchedulerData->mbDelete && (mnUpdateStack <= nUpdateStack); -} - -void Scheduler::ImplDispose() -{ - mpSchedulerData->mpScheduler = NULL; - delete mpSchedulerData; - mpSchedulerData = NULL; -} - -void Scheduler::ImplInitScheduler() -{ - ImplSVData* pSVData = ImplGetSVData(); - - if(pSVData->maSchedulers == NULL) - pSVData->maSchedulers = new ImplScheduler_t; -} - - -bool Scheduler::ImplHandleTaskScheduling(sal_uInt64 &nMinPeriod, sal_uInt64 nTime) -{ - // process all pending Tasks - if( !mbInScheduler ) - { - // Should Task be released from scheduling? - if ( !mpSchedulerData->mbDelete ) - { - mnUpdateStack = 0; - nMinPeriod = UpdateMinPeriod( nMinPeriod, nTime ); - } - else - { - ImplDispose(); - return true; - } - } - - return false; -} |