[Libreoffice-commits] core.git: include/vcl vcl/source

Michael Meeks michael.meeks at collabora.com
Wed Nov 25 15:22:39 PST 2015


 include/vcl/idle.hxx         |    3 ++-
 include/vcl/scheduler.hxx    |   11 +++++++++--
 include/vcl/timer.hxx        |    3 ++-
 vcl/source/app/idle.cxx      |   10 ++++++++--
 vcl/source/app/scheduler.cxx |   21 ++++++++++++++++++---
 vcl/source/app/timer.cxx     |    9 +++++++--
 6 files changed, 46 insertions(+), 11 deletions(-)

New commits:
commit 10a451e97992ce42db3cefa3bffb883f310767c9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Wed Nov 25 21:33:15 2015 +0000

    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 at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
index d746cf4..5460d33 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 b1152a0..da9af64 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -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 );
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index 94a025e..149ba90 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 198ccfc..123f37a 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -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
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 8e548bc..265d6f6 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 cb00fab..1766d7f 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -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


More information about the Libreoffice-commits mailing list