diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2022-11-21 17:41:58 +0000 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-12-20 09:21:51 +0000 |
commit | 50a08d1eb47f8faeb511cec43d1f8ba12b8f27f7 (patch) | |
tree | 63ddc6c49a63770d3eecbecd908fcf9485e90325 | |
parent | 5f0cf6e7aa75e8724e13e731be09271c7e536e93 (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.cxx | 41 |
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&) { |