vcl/source/app/scheduler.cxx | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-)
New commits: commit 50a08d1eb47f8faeb511cec43d1f8ba12b8f27f7 Author: Michael Meeks <[email protected]> AuthorDate: Mon Nov 21 17:41:58 2022 +0000 Commit: Noel Grandin <[email protected]> CommitDate: Tue Dec 20 09:21:51 2022 +0000 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 <[email protected]> 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&) {
