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&)
     {

Reply via email to