vcl: don't treat non-ready timers as idle handlers.
Fixes the busy-loop - 100% CPU all the time. Change-Id: I965f62d6a6f2ec1830c0897dd97179a739c70afc Reviewed-on: https://gerrit.libreoffice.org/20186 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>
This commit is contained in:
parent
9c554c2c8c
commit
10a451e979
6 changed files with 46 additions and 11 deletions
|
@ -39,7 +39,8 @@ public:
|
|||
void SetIdleHdl( const Link<Idle *, void>& rLink ) { maIdleHdl = rLink; }
|
||||
const Link<Idle *, void>& GetIdleHdl() const { return maIdleHdl; }
|
||||
virtual void Invoke() override;
|
||||
virtual bool ReadyForSchedule( bool bTimer ) const override;
|
||||
virtual bool ReadyForSchedule( bool bTimerOnly, sal_uInt64 nTimeNow ) const override;
|
||||
virtual bool IsIdle() const override;
|
||||
virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const override;
|
||||
Idle& operator=( const Idle& rIdle );
|
||||
};
|
||||
|
|
|
@ -56,8 +56,15 @@ protected:
|
|||
|
||||
friend struct ImplSchedulerData;
|
||||
virtual void SetDeletionFlags();
|
||||
virtual bool ReadyForSchedule( bool bTimer ) const = 0;
|
||||
virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const = 0;
|
||||
/// Is this item ready to be dispatched at @nTimeNow
|
||||
virtual bool ReadyForSchedule( bool bTimerOnly, sal_uInt64 nTimeNow ) const = 0;
|
||||
/// Schedule only when other timers and events are processed
|
||||
virtual bool IsIdle() const = 0;
|
||||
/**
|
||||
* Adjust @nMinPeriod downwards if we want to be notified before
|
||||
* then, @nTimeNow is the current time.
|
||||
*/
|
||||
virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const = 0;
|
||||
|
||||
public:
|
||||
Scheduler( const sal_Char *pDebugName = nullptr );
|
||||
|
|
|
@ -31,7 +31,8 @@ protected:
|
|||
bool mbAuto;
|
||||
|
||||
virtual void SetDeletionFlags() override;
|
||||
virtual bool ReadyForSchedule( bool bTimer ) const override;
|
||||
virtual bool ReadyForSchedule( bool bTimerOnly, sal_uInt64 nTimeNow ) const override;
|
||||
virtual bool IsIdle() const override;
|
||||
virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const override;
|
||||
|
||||
public:
|
||||
|
|
|
@ -47,9 +47,15 @@ void Idle::Start()
|
|||
Scheduler::ImplStartTimer(Scheduler::ImmediateTimeoutMs);
|
||||
}
|
||||
|
||||
bool Idle::ReadyForSchedule( bool bTimer ) const
|
||||
bool Idle::ReadyForSchedule( bool bTimerOnly, sal_uInt64 /* nTimeNow */ ) const
|
||||
{
|
||||
return !bTimer;
|
||||
// always ready if not only looking for timers.
|
||||
return !bTimerOnly;
|
||||
}
|
||||
|
||||
bool Idle::IsIdle() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 /* nTime */ ) const
|
||||
|
|
|
@ -46,10 +46,11 @@ ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimerOnly )
|
|||
ImplSVData* pSVData = ImplGetSVData();
|
||||
ImplSchedulerData *pMostUrgent = nullptr;
|
||||
|
||||
sal_uInt64 nTimeNow = tools::Time::GetSystemTicks();
|
||||
for ( ImplSchedulerData *pSchedulerData = pSVData->mpFirstSchedulerData; pSchedulerData; pSchedulerData = pSchedulerData->mpNext )
|
||||
{
|
||||
if ( !pSchedulerData->mpScheduler || pSchedulerData->mbDelete ||
|
||||
!pSchedulerData->mpScheduler->ReadyForSchedule( bTimerOnly ) ||
|
||||
!pSchedulerData->mpScheduler->ReadyForSchedule( bTimerOnly, nTimeNow ) ||
|
||||
!pSchedulerData->mpScheduler->IsActive())
|
||||
continue;
|
||||
if (!pMostUrgent)
|
||||
|
@ -207,10 +208,24 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles )
|
|||
{
|
||||
if (!pSchedulerData->mbInScheduler)
|
||||
{
|
||||
if ( pSchedulerData->mpScheduler->ReadyForSchedule( true ) )
|
||||
nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime );
|
||||
// FIXME: move into a helper.
|
||||
const char *pSchedulerName = pSchedulerData->mpScheduler->mpDebugName;
|
||||
if (!pSchedulerName)
|
||||
pSchedulerName = "unknown";
|
||||
|
||||
if ( !pSchedulerData->mpScheduler->IsIdle() )
|
||||
{
|
||||
sal_uInt64 nOldMinPeriod = nMinPeriod;
|
||||
nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod(
|
||||
nOldMinPeriod, nTime );
|
||||
SAL_INFO("vcl.schedule", "Have active timer " << pSchedulerName <<
|
||||
"update min period from " << nOldMinPeriod << " to " << nMinPeriod);
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_INFO("vcl.schedule", "Have active idle " << pSchedulerName);
|
||||
bHasActiveIdles = true;
|
||||
}
|
||||
}
|
||||
pPrevSchedulerData = pSchedulerData;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,14 @@ void Timer::SetDeletionFlags()
|
|||
}
|
||||
}
|
||||
|
||||
bool Timer::ReadyForSchedule( bool /* bTimerOnly */ ) const
|
||||
bool Timer::ReadyForSchedule( bool /* bTimerOnly */, sal_uInt64 nTimeNow ) const
|
||||
{
|
||||
return (mpSchedulerData->mnUpdateTime + mnTimeout) <= tools::Time::GetSystemTicks();
|
||||
return (mpSchedulerData->mnUpdateTime + mnTimeout) <= nTimeNow;
|
||||
}
|
||||
|
||||
bool Timer::IsIdle() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const
|
||||
|
|
Loading…
Reference in a new issue