diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx index cb96c09864c5..18d4e8abaab7 100644 --- a/include/vcl/idle.hxx +++ b/include/vcl/idle.hxx @@ -35,8 +35,8 @@ private: sal_uInt64 GetTimeout() const = delete; protected: - virtual bool ReadyForSchedule( sal_uInt64 nTimeNow ) const override; - virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override; + virtual sal_uInt64 UpdateMinPeriod( + sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override; Idle( bool bAuto, const sal_Char *pDebugName = nullptr ); diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx index 669a402f73d6..ff5885edb36f 100644 --- a/include/vcl/scheduler.hxx +++ b/include/vcl/scheduler.hxx @@ -35,9 +35,6 @@ class VCL_DLLPUBLIC Scheduler final static inline bool HasPendingTasks( const ImplSchedulerContext &rSchedCtx, const sal_uInt64 nTime ); - static inline void UpdateMinPeriod( ImplSchedulerData *pSchedulerData, - sal_uInt64 nTime, sal_uInt64 &nMinPeriod ); - static inline void UpdateSystemTimer( ImplSchedulerContext &rSchedCtx, sal_uInt64 nMinPeriod, bool bForce, sal_uInt64 nTime ); diff --git a/include/vcl/task.hxx b/include/vcl/task.hxx index 21eb934fee6d..5148ac31bebf 100644 --- a/include/vcl/task.hxx +++ b/include/vcl/task.hxx @@ -56,11 +56,18 @@ protected: const ImplSchedulerData* GetSchedulerData() const { return mpSchedulerData; } virtual void SetDeletionFlags(); - /// Is this item ready to be dispatched at nTimeNow - virtual bool ReadyForSchedule( sal_uInt64 nTimeNow ) const = 0; + /** - * Adjust nMinPeriod downwards if we want to be notified before - * then, nTimeNow is the current time. + * How long (in MS) until the Task is ready to be dispatched? + * + * Simply return Scheduler::ImmediateTimeoutMs if you're ready, like an + * Idle. If you have to return Scheduler::InfiniteTimeoutMs, you probably + * need an other mechanism to wake up the Scheduler or rely on other + * Tasks to be scheduled, or simply use a polling Timer. + * + * @param nMinPeriod the currently expected sleep time + * @param nTimeNow the current time + * @return the sleep time of the Task to become ready */ virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const = 0; diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx index 5be766cb6aa7..d26004cc5312 100644 --- a/include/vcl/timer.hxx +++ b/include/vcl/timer.hxx @@ -31,8 +31,8 @@ class VCL_DLLPUBLIC Timer : public Task protected: virtual void SetDeletionFlags() override; - virtual bool ReadyForSchedule( sal_uInt64 nTimeNow ) const override; - virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override; + virtual sal_uInt64 UpdateMinPeriod( + sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override; Timer( bool bAuto, const sal_Char *pDebugName = nullptr ); diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx index 4cbd3f8c0ed6..78c114801868 100644 --- a/vcl/source/app/idle.cxx +++ b/vcl/source/app/idle.cxx @@ -55,11 +55,6 @@ void Idle::Start() Task::StartTimer(nPeriod); } -bool Idle::ReadyForSchedule( sal_uInt64 /* nTimeNow */ ) const -{ - return true; -} - sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 /* nMinPeriod */, sal_uInt64 /* nTimeNow */ ) const { return Scheduler::ImmediateTimeoutMs; diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index d97233cad096..8e5031a3e527 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -172,19 +172,6 @@ bool Scheduler::GetDeterministicMode() return g_bDeterministicMode; } -inline void Scheduler::UpdateMinPeriod( ImplSchedulerData * const pSchedulerData, - const sal_uInt64 nTime, sal_uInt64 &nMinPeriod ) -{ - if ( nMinPeriod > ImmediateTimeoutMs ) - { - sal_uInt64 nCurPeriod = nMinPeriod; - nMinPeriod = pSchedulerData->mpTask->UpdateMinPeriod( nCurPeriod, nTime ); - assert( nMinPeriod <= nCurPeriod ); - if ( nCurPeriod < nMinPeriod ) - nMinPeriod = nCurPeriod; - } -} - inline void Scheduler::UpdateSystemTimer( ImplSchedulerContext &rSchedCtx, const sal_uInt64 nMinPeriod, const bool bForce, const sal_uInt64 nTime ) @@ -254,6 +241,8 @@ bool Scheduler::ProcessTaskScheduling() ImplSchedulerData *pMostUrgent = nullptr; ImplSchedulerData *pPrevMostUrgent = nullptr; sal_uInt64 nMinPeriod = InfiniteTimeoutMs; + sal_uInt64 nMostUrgentPeriod = InfiniteTimeoutMs; + sal_uInt64 nReadyPeriod = InfiniteTimeoutMs; DBG_TESTSOLARMUTEX(); @@ -298,16 +287,18 @@ bool Scheduler::ProcessTaskScheduling() goto next_entry; // skip ready tasks with lower priority than the most urgent (numerical lower is higher) - if ( pSchedulerData->mpTask->ReadyForSchedule( nTime ) && + nReadyPeriod = pSchedulerData->mpTask->UpdateMinPeriod( nMinPeriod, nTime ); + if ( ImmediateTimeoutMs == nReadyPeriod && (!pMostUrgent || (pSchedulerData->mpTask->GetPriority() < pMostUrgent->mpTask->GetPriority())) ) { - if ( pMostUrgent ) - UpdateMinPeriod( pMostUrgent, nTime, nMinPeriod ); + if ( pMostUrgent && nMinPeriod > nMostUrgentPeriod ) + nMinPeriod = nMostUrgentPeriod; pPrevMostUrgent = pPrevSchedulerData; pMostUrgent = pSchedulerData; + nMostUrgentPeriod = nReadyPeriod; } - else - UpdateMinPeriod( pSchedulerData, nTime, nMinPeriod ); + else if ( nMinPeriod > nReadyPeriod ) + nMinPeriod = nReadyPeriod; next_entry: pPrevSchedulerData = pSchedulerData; @@ -360,7 +351,9 @@ next_entry: if ( pMostUrgent->mpTask && pMostUrgent->mpTask->IsActive() ) { pMostUrgent->mnUpdateTime = nTime; - UpdateMinPeriod( pMostUrgent, nTime, nMinPeriod ); + nReadyPeriod = pMostUrgent->mpTask->UpdateMinPeriod( nMinPeriod, nTime ); + if ( nMinPeriod > nReadyPeriod ) + nMinPeriod = nReadyPeriod; UpdateSystemTimer( rSchedCtx, nMinPeriod, false, nTime ); } } diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx index 18796806a318..6cba9e2f2b2f 100644 --- a/vcl/source/app/timer.cxx +++ b/vcl/source/app/timer.cxx @@ -30,21 +30,11 @@ void Timer::SetDeletionFlags() Task::SetDeletionFlags(); } -bool Timer::ReadyForSchedule( sal_uInt64 nTimeNow ) const -{ - return (GetSchedulerData()->mnUpdateTime + mnTimeout) <= nTimeNow; -} - -sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const +sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64, sal_uInt64 nTimeNow ) const { sal_uInt64 nWakeupTime = GetSchedulerData()->mnUpdateTime + mnTimeout; - if( nWakeupTime <= nTimeNow ) - return Scheduler::ImmediateTimeoutMs; - else - { - sal_uInt64 nSleepTime = nWakeupTime - nTimeNow; - return ( nSleepTime < nMinPeriod ) ? nSleepTime : nMinPeriod; - } + return ( nWakeupTime <= nTimeNow ) + ? Scheduler::ImmediateTimeoutMs : nWakeupTime - nTimeNow; } Timer::Timer( bool bAuto, const sal_Char *pDebugName )