Kaydet (Commit) 10a451e9 authored tarafından Michael Meeks's avatar Michael Meeks

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/20186Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Tested-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst 9c554c2c
...@@ -39,7 +39,8 @@ public: ...@@ -39,7 +39,8 @@ public:
void SetIdleHdl( const Link<Idle *, void>& rLink ) { maIdleHdl = rLink; } void SetIdleHdl( const Link<Idle *, void>& rLink ) { maIdleHdl = rLink; }
const Link<Idle *, void>& GetIdleHdl() const { return maIdleHdl; } const Link<Idle *, void>& GetIdleHdl() const { return maIdleHdl; }
virtual void Invoke() override; 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; virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const override;
Idle& operator=( const Idle& rIdle ); Idle& operator=( const Idle& rIdle );
}; };
......
...@@ -56,8 +56,15 @@ protected: ...@@ -56,8 +56,15 @@ protected:
friend struct ImplSchedulerData; friend struct ImplSchedulerData;
virtual void SetDeletionFlags(); virtual void SetDeletionFlags();
virtual bool ReadyForSchedule( bool bTimer ) const = 0; /// Is this item ready to be dispatched at @nTimeNow
virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const = 0; 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: public:
Scheduler( const sal_Char *pDebugName = nullptr ); Scheduler( const sal_Char *pDebugName = nullptr );
......
...@@ -31,7 +31,8 @@ protected: ...@@ -31,7 +31,8 @@ protected:
bool mbAuto; bool mbAuto;
virtual void SetDeletionFlags() override; 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; virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const override;
public: public:
......
...@@ -47,9 +47,15 @@ void Idle::Start() ...@@ -47,9 +47,15 @@ void Idle::Start()
Scheduler::ImplStartTimer(Scheduler::ImmediateTimeoutMs); 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 sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 /* nTime */ ) const
......
...@@ -46,10 +46,11 @@ ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimerOnly ) ...@@ -46,10 +46,11 @@ ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimerOnly )
ImplSVData* pSVData = ImplGetSVData(); ImplSVData* pSVData = ImplGetSVData();
ImplSchedulerData *pMostUrgent = nullptr; ImplSchedulerData *pMostUrgent = nullptr;
sal_uInt64 nTimeNow = tools::Time::GetSystemTicks();
for ( ImplSchedulerData *pSchedulerData = pSVData->mpFirstSchedulerData; pSchedulerData; pSchedulerData = pSchedulerData->mpNext ) for ( ImplSchedulerData *pSchedulerData = pSVData->mpFirstSchedulerData; pSchedulerData; pSchedulerData = pSchedulerData->mpNext )
{ {
if ( !pSchedulerData->mpScheduler || pSchedulerData->mbDelete || if ( !pSchedulerData->mpScheduler || pSchedulerData->mbDelete ||
!pSchedulerData->mpScheduler->ReadyForSchedule( bTimerOnly ) || !pSchedulerData->mpScheduler->ReadyForSchedule( bTimerOnly, nTimeNow ) ||
!pSchedulerData->mpScheduler->IsActive()) !pSchedulerData->mpScheduler->IsActive())
continue; continue;
if (!pMostUrgent) if (!pMostUrgent)
...@@ -207,10 +208,24 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles ) ...@@ -207,10 +208,24 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles )
{ {
if (!pSchedulerData->mbInScheduler) if (!pSchedulerData->mbInScheduler)
{ {
if ( pSchedulerData->mpScheduler->ReadyForSchedule( true ) ) // FIXME: move into a helper.
nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime ); 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 else
{
SAL_INFO("vcl.schedule", "Have active idle " << pSchedulerName);
bHasActiveIdles = true; bHasActiveIdles = true;
}
} }
pPrevSchedulerData = pSchedulerData; pPrevSchedulerData = pSchedulerData;
} }
......
...@@ -31,9 +31,14 @@ void Timer::SetDeletionFlags() ...@@ -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 sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment