summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-11-24 16:59:29 +0000
committerMichael Meeks <michael.meeks@collabora.com>2015-11-24 19:46:02 +0000
commit87199d3829257420429057336283c55be6ae7481 (patch)
tree40f63144f9b20cebbaa6cb6fd64184e27c7b192f
parent9b52b8999be86e5c6e5f5901b2640b16f08a2323 (diff)
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@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>
-rw-r--r--include/vcl/scheduler.hxx2
-rw-r--r--vcl/source/app/idle.cxx5
-rw-r--r--vcl/source/app/scheduler.cxx31
-rw-r--r--vcl/source/app/svapp.cxx9
4 files changed, 27 insertions, 20 deletions
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index be9df9e69e5a..5771f3af782f 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 5ce53613bc4d..bba2d050c2c4 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 b5e64e243801..743de911cd22 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 734b5def9f1f..808e743bdbc9 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