summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2022-11-21 17:41:58 +0000
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-12-20 09:21:51 +0000
commit50a08d1eb47f8faeb511cec43d1f8ba12b8f27f7 (patch)
tree63ddc6c49a63770d3eecbecd908fcf9485e90325
parent5f0cf6e7aa75e8724e13e731be09271c7e536e93 (diff)
tdf#148434 - avoid strange OS/X deadlock around AnyInput.
Apparently calling AnyInput on Mac and filtering for just input, gives you window creation / re-sizing events which then trigger idle paint events which then deadlock if called with the scheduler lock. Try having a little more inefficiency and a different race for this case to handle the Mac world. Change-Id: I9985eaf18f8d0ba4d44e83c03746510a6ba6d664 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143046 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--vcl/source/app/scheduler.cxx41
1 files changed, 19 insertions, 22 deletions
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 251b972fe5ac..1f8f3034bc58 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -419,24 +419,6 @@ void Scheduler::CallbackTaskScheduling()
break;
}
-// tdf#148435 Apparently calling AnyInput on Mac and filtering for just input, gives
-// you window creation / re-sizing events which then trigger idle paint
-// events which then deadlock if called with the scheduler lock.
-// So since this is an optimisation, just don't do this on mac.
-#ifndef MACOSX
- // Delay invoking tasks with idle priorities as long as there are user input or repaint events
- // in the OS event queue. This will often effectively compress such events and repaint only
- // once at the end, improving performance in cases such as repeated zooming with a complex document.
- if ( pMostUrgent && pMostUrgent->mePriority >= TaskPriority::HIGH_IDLE
- && Application::AnyInput( VclInputFlags::MOUSE | VclInputFlags::KEYBOARD | VclInputFlags::PAINT ))
- {
- SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks()
- << " idle priority task " << pMostUrgent << " delayed, system events pending" );
- pMostUrgent = nullptr;
- nMinPeriod = 0;
- }
-#endif
-
if (InfiniteTimeoutMs != nMinPeriod)
SAL_INFO("vcl.schedule",
"Calculated minimum timeout as " << nMinPeriod << " of " << nTasks << " tasks");
@@ -452,9 +434,6 @@ void Scheduler::CallbackTaskScheduling()
comphelper::ProfileZone aZone( pTask->GetDebugName() );
- // prepare Scheduler object for deletion after handling
- pTask->SetDeletionFlags();
-
assert(!pMostUrgent->mbInScheduler);
pMostUrgent->mbInScheduler = true;
@@ -464,8 +443,17 @@ void Scheduler::CallbackTaskScheduling()
rSchedCtx.mpSchedulerStack = pMostUrgent;
rSchedCtx.mpSchedulerStackTop = pMostUrgent;
+ bool bIsHighPriorityIdle = pMostUrgent->mePriority >= TaskPriority::HIGH_IDLE;
+
// invoke the task
Unlock();
+
+ // Delay invoking tasks with idle priorities as long as there are user input or repaint events
+ // in the OS event queue. This will often effectively compress such events and repaint only
+ // once at the end, improving performance in cases such as repeated zooming with a complex document.
+ bool bDelayInvoking = bIsHighPriorityIdle &&
+ Application::AnyInput( VclInputFlags::MOUSE | VclInputFlags::KEYBOARD | VclInputFlags::PAINT );
+
/*
* Current policy is that scheduler tasks aren't allowed to throw an exception.
* Because otherwise the exception is caught somewhere totally unrelated.
@@ -475,7 +463,16 @@ void Scheduler::CallbackTaskScheduling()
*/
try
{
- pTask->Invoke();
+ if (bDelayInvoking)
+ SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks()
+ << " idle priority task " << pTask->GetDebugName()
+ << " delayed, system events pending" );
+ else
+ {
+ // prepare Scheduler object for deletion after handling
+ pTask->SetDeletionFlags();
+ pTask->Invoke();
+ }
}
catch (css::uno::Exception&)
{