[Libreoffice-commits] core.git: vcl/inc vcl/win

Jan-Marek Glogowski glogow at fbihome.de
Tue Aug 1 16:54:50 UTC 2017


 vcl/inc/win/saldata.hxx  |    2 +-
 vcl/win/app/salinst.cxx  |   39 +++++++++++++--------------------------
 vcl/win/app/saltimer.cxx |   22 ++++++----------------
 3 files changed, 20 insertions(+), 43 deletions(-)

New commits:
commit 50799a721c7ddcf9475a1b79984ed64ddd7cdf57
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Mon Jul 31 19:49:34 2017 +0200

    tdf#109997 WIN don't post a callback event directly
    
    I doesn't seem possible to post an event deterministically to the
    end of the Windows message queue and then process this queued
    events "in order".
    
    PeekMessage and now even DispatchMessage process events out of
    order - that's how this assert was hit. I was quite sure it would
    not hit, but a simple resize proved me wrong. And the assert just
    proved that all my assumptions were wrong :-(
    
    So this gives up the whole idea of a short-circuit message queue
    handling on Windows for busy processing of LO Idles and goes back
    to some kind of the original "always timer" implementation. Since
    the "parallel" processing of LO events after system messages
    during DoYield  was dropped, this might be slower; or not.
    
    In the end this simplifies the main loop almost to the starting
    point, except for a little busy loop, if we wait for an Idle event
    timer - not so busy acually, as we just switch to another local
    thread, which hopefully is our idle timer waiting to fire.
    A short-circuit with a little detour.
    
    Change-Id: Id63a2a9e2a3b1501ad50a2c6f308a36efe55e68f

diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index ed1d225b14b8..9ad5d9cfddf1 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -85,7 +85,7 @@ public:
     BYTE*                   mpDitherLow;            // Dither mapping table
     BYTE*                   mpDitherHigh;           // Dither mapping table
     HANDLE                  mnTimerId;              ///< Windows timer id
-    bool                    mbOnIdleRunScheduler;   ///< Run the scheduler, if yield is idle
+    bool                    mbOnIdleRunScheduler;   ///< Run yield until the scheduler processed the idle
     HHOOK                   mhSalObjMsgHook;        // hook to get interesting msg for SalObject
     HWND                    mhWantLeaveMsg;         // window handle, that want a MOUSELEAVE message
     AutoTimer*              mpMouseLeaveTimer;      // Timer for MouseLeave Test
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index 6458fca73c43..7ea3bd526675 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -575,29 +575,20 @@ ImplSalYield( bool bWait, bool bHandleAllCurrentEvents )
         if ( bOneEvent )
         {
             bWasMsg = true;
-            if ( !(aMsg.message == SAL_MSG_TIMER_CALLBACK && 1 == aMsg.wParam) )
-            {
-                TranslateMessage( &aMsg );
-                ImplSalDispatchMessage( &aMsg );
-            }
-            else
-            {
-                // This is just the scheduler wakeup message, in case we're
-                // waiting in GetMessageW
-                // So we can just drop it, but we have to fix the accounting!
-                assert( pSalData->mbOnIdleRunScheduler );
-                ++nMaxEvents;
-            }
+            TranslateMessage( &aMsg );
+            ImplSalDispatchMessage( &aMsg );
         }
         else
-        {
-            if ( nMaxEvents && pSalData->mbOnIdleRunScheduler )
+            // busy loop to catch the 0ms timeout
+            // We don't need to busy loop, if we wait anyway.
+            // Even if we didn't process the event directly, report it.
+            if ( pSalData->mbOnIdleRunScheduler && !bWait )
             {
-                pSalData->mbOnIdleRunScheduler = false;
-                EmitTimerCallback();
+                SwitchToThread();
+                nMaxEvents++;
                 bOneEvent = true;
+                bWasMsg = true;
             }
-        }
     } while( --nMaxEvents && bOneEvent );
 
     // Also check that we don't wait when application already has quit
@@ -606,11 +597,8 @@ ImplSalYield( bool bWait, bool bHandleAllCurrentEvents )
         if ( GetMessageW( &aMsg, nullptr, 0, 0 ) )
         {
             // Ignore the scheduler wakeup message
-            if ( !(aMsg.message == SAL_MSG_TIMER_CALLBACK && 1 == aMsg.wParam) )
-            {
-                TranslateMessage( &aMsg );
-                ImplSalDispatchMessage( &aMsg );
-            }
+            TranslateMessage( &aMsg );
+            ImplSalDispatchMessage( &aMsg );
         }
     }
     return bWasMsg;
@@ -735,9 +723,8 @@ LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, i
             while ( PeekMessageW(&aMsg, nullptr, SAL_MSG_TIMER_CALLBACK,
                                  SAL_MSG_TIMER_CALLBACK, PM_REMOVE | PM_NOYIELD | PM_QS_POSTMESSAGE) )
                 assert( "Multiple timer messages in queue" );
-            assert( 0 == wParam );
-            if ( 0 == wParam )
-                EmitTimerCallback();
+            GetSalData()->mbOnIdleRunScheduler = false;
+            EmitTimerCallback();
             break;
     }
 
diff --git a/vcl/win/app/saltimer.cxx b/vcl/win/app/saltimer.cxx
index 847ff52851b8..d57eefd63efc 100644
--- a/vcl/win/app/saltimer.cxx
+++ b/vcl/win/app/saltimer.cxx
@@ -53,7 +53,6 @@ void ImplSalStopTimer()
                          SAL_MSG_TIMER_CALLBACK, PM_REMOVE | PM_NOYIELD | PM_QS_POSTMESSAGE) )
         nMsgCount++;
     assert( nMsgCount <= 1 );
-    pSalData->mbOnIdleRunScheduler = false;
 }
 
 void ImplSalStartTimer( sal_uLong nMS )
@@ -68,22 +67,13 @@ void ImplSalStartTimer( sal_uLong nMS )
     // cannot change a one-shot timer, so delete it and create a new one
     ImplSalStopTimer();
 
-    // run the scheduler, if yield is idle for the 0ms case
+    // keep the scheduler running, if a 0ms timer / Idle is scheduled
     pSalData->mbOnIdleRunScheduler = ( 0 == nMS );
-    if ( pSalData->mbOnIdleRunScheduler )
-    {
-        BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd,
-                                      SAL_MSG_TIMER_CALLBACK, 1, 0);
-        SAL_WARN_IF(0 == ret, "vcl", "ERROR: PostMessage() failed!");
-    }
-    else
-    {
-        // probably WT_EXECUTEONLYONCE is not needed, but it enforces Period
-        // to be 0 and should not hurt; also see
-        // https://www.microsoft.com/msj/0499/pooling/pooling.aspx
-        CreateTimerQueueTimer(&pSalData->mnTimerId, nullptr, SalTimerProc, nullptr,
-                              nMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
-    }
+    // probably WT_EXECUTEONLYONCE is not needed, but it enforces Period
+    // to be 0 and should not hurt; also see
+    // https://www.microsoft.com/msj/0499/pooling/pooling.aspx
+    CreateTimerQueueTimer(&pSalData->mnTimerId, nullptr, SalTimerProc, nullptr,
+                          nMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
 }
 
 WinSalTimer::~WinSalTimer()


More information about the Libreoffice-commits mailing list