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

Michael Meeks michael.meeks at collabora.com
Tue Nov 24 11:46:33 PST 2015


 include/vcl/scheduler.hxx    |    2 +-
 vcl/source/app/idle.cxx      |    5 +----
 vcl/source/app/scheduler.cxx |   31 +++++++++++++++++--------------
 vcl/source/app/svapp.cxx     |    9 ++++++++-
 4 files changed, 27 insertions(+), 20 deletions(-)

New commits:
commit 87199d3829257420429057336283c55be6ae7481
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Nov 24 16:59:29 2015 +0000

    vcl: re-introduce idle handling.
    
    The idea here is that we should process 'idle' events - like re-paint
    after we have processed any OS messages - such as key/mouse input,
    window re-size events etc.
    
    The previous approach wasn't achieving this - it was processing a single
    idle event each time around the main-loop iteration; urk.
    
    Lubos implemented something -like- this, the vestiges of it need cleaning
    up and removing in: 06d731428ef6cf93c7333e8228bfb6088853b52f but it was
    disabled (most likely because it broke gtk in tdf#91727, which was itself
    broken by using silly values for timeouts in the scheduler (now fixed))
    
    Tested on Windows, gtk, kde4, unx-generic.
    
    Change-Id: I7756bca874779c00f72b372cacb7745d0f189f66
    Reviewed-on: https://gerrit.libreoffice.org/20158
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index be9df9e..5771f3a 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -94,7 +94,7 @@ public:
     // Process one pending Timer with highhest priority
     static void CallbackTaskScheduling( bool ignore );
     /// Calculate minimum timeout - and return its value.
-    static sal_uInt64 CalculateMinimumTimeout();
+    static sal_uInt64 CalculateMinimumTimeout( bool &bHasActiveIdles );
     /// Process one pending task ahead of time with highhest priority.
     static void       ProcessTaskScheduling( bool bTimer );
 };
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 5ce5361..bba2d05 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -48,10 +48,7 @@ void Idle::Start()
 
 bool Idle::ReadyForSchedule( bool bTimer ) const
 {
-    // tdf#91727 - We need to re-work this to allow only UI idle handlers
-    //             and not timeouts to be processed in some limited scenarios
-    (void)bTimer;
-    return true; // !bTimer
+    return !bTimer;
 }
 
 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 b5e64e2..743de91 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -153,7 +153,7 @@ void Scheduler::CallbackTaskScheduling(bool ignore)
 {
     // this function is for the saltimer callback
     (void)ignore;
-    Scheduler::ProcessTaskScheduling( true );
+    Scheduler::ProcessTaskScheduling( false );
 }
 
 void Scheduler::ProcessTaskScheduling( bool bTimerOnly )
@@ -168,7 +168,7 @@ void Scheduler::ProcessTaskScheduling( bool bTimerOnly )
     }
 }
 
-sal_uInt64 Scheduler::CalculateMinimumTimeout()
+sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles )
 {
     // process all pending Tasks
     // if bTimer True, only handle timer
@@ -181,13 +181,11 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout()
     pSchedulerData = pSVData->mpFirstSchedulerData;
     while ( pSchedulerData )
     {
-        if( pSchedulerData->mbInScheduler )
-        {
-            pPrevSchedulerData = pSchedulerData;
-            pSchedulerData = pSchedulerData->mpNext;
-        }
+        ImplSchedulerData *pNext = pSchedulerData->mpNext;
+
         // Should Task be released from scheduling?
-        else if ( pSchedulerData->mbDelete )
+        if ( !pSchedulerData->mbInScheduler &&
+              pSchedulerData->mbDelete )
         {
             if ( pPrevSchedulerData )
                 pPrevSchedulerData->mpNext = pSchedulerData->mpNext;
@@ -195,19 +193,24 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout()
                 pSVData->mpFirstSchedulerData = pSchedulerData->mpNext;
             if ( pSchedulerData->mpScheduler )
                 pSchedulerData->mpScheduler->mpSchedulerData = nullptr;
-            ImplSchedulerData* pTempSchedulerData = pSchedulerData;
-            pSchedulerData = pSchedulerData->mpNext;
-            delete pTempSchedulerData;
+            pNext = pSchedulerData->mpNext;
+            delete pSchedulerData;
         }
         else
         {
-            nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime );
+            if (!pSchedulerData->mbInScheduler)
+            {
+                if ( pSchedulerData->mpScheduler->ReadyForSchedule( true ) )
+                    nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime );
+                else
+                    bHasActiveIdles = true;
+            }
             pPrevSchedulerData = pSchedulerData;
-            pSchedulerData = pSchedulerData->mpNext;
         }
+        pSchedulerData = pNext;
     }
 
-    // delete clock if no more timers available
+    // delete clock if no more timers available,
     if ( !pSVData->mpFirstSchedulerData )
     {
         if ( pSVData->mpSalTimer )
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 734b5de..808e743 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -477,18 +477,25 @@ inline void ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased
 {
     ImplSVData* pSVData = ImplGetSVData();
 
+    bool bHasActiveIdles = false;
     sal_uInt64 nMinTimeout = 0;
     if (nReleased == 0) // else thread doesn't have SolarMutex so avoid race
-        nMinTimeout = Scheduler::CalculateMinimumTimeout();
+        nMinTimeout = Scheduler::CalculateMinimumTimeout(bHasActiveIdles);
 
     // FIXME: should use returned value as param to DoYield
     (void)nMinTimeout;
 
+    // If we have idles, don't wait for the timeout; check for events
+    // and come back as quick as possible.
+    if (bHasActiveIdles)
+        i_bWait = false;
+
     // TODO: there's a data race here on WNT only because ImplYield may be
     // called without SolarMutex; if we can get rid of LazyDelete (with VclPtr)
     // then the only remaining use of mnDispatchLevel is in OSX specific code
     // so that would effectively eliminate the race on WNT
     pSVData->maAppData.mnDispatchLevel++;
+
     // do not wait for events if application was already quit; in that
     // case only dispatch events already available
     // do not wait for events either if the app decided that it is too busy for timers


More information about the Libreoffice-commits mailing list