summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-11-25 21:33:15 +0000
committerMichael Meeks <michael.meeks@collabora.com>2015-11-26 22:17:33 +0000
commit695bb66fa3b594d29f8aa9d880212df5588cfb91 (patch)
tree92ab236e9d2c152afdc9533fe4004627ab1723e0
parent0b533c23ef71d77fb5112769908fa9f39d5f552d (diff)
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>
-rw-r--r--include/vcl/idle.hxx3
-rw-r--r--include/vcl/scheduler.hxx11
-rw-r--r--include/vcl/timer.hxx3
-rw-r--r--vcl/source/app/idle.cxx10
-rw-r--r--vcl/source/app/scheduler.cxx21
-rw-r--r--vcl/source/app/timer.cxx9
6 files changed, 46 insertions, 11 deletions
diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
index d746cf45e775..5460d3302635 100644
--- a/include/vcl/idle.hxx
+++ b/include/vcl/idle.hxx
@@ -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 );
};
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index 5771f3af782f..58da1bf1c1c7 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -67,8 +67,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 );
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index 94a025ecd697..149ba9099ac9 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -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:
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index bba2d050c2c4..9374b0302d40 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -46,9 +46,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
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 8e548bc5cb42..265d6f64c332 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -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;
}
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index 4b0961e01c65..cf0a536f6fa7 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -30,9 +30,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