include/systools/win32/wait_for_multiple_objects.hxx |   37 ++++++++++++++++++
 sal/osl/w32/conditn.cxx                              |   39 ++++---------------
 vcl/win/dtrans/MtaOleClipb.cxx                       |   29 +-------------
 3 files changed, 49 insertions(+), 56 deletions(-)

New commits:
commit 6b6f8ca3dd4aa145519f5961f822435607d0e1d1
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri Jan 10 16:19:10 2025 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Jan 10 14:12:52 2025 +0100

    Factor out and simplify COM-safe wait
    
    Before commit 1e2e51607a163021ef1fb1fb0d217266bd448173 (Try to use
    CoWaitForMultipleHandles magic to handle COM message loop, 2025-01-10)
    osl_waitCondition didn't adjust the timeout value in the COM message
    processing loop. The abovementioned commit started to use a function
    that pumps the message loop itself, but the code for manual pumping
    wasn't removed (it has (likely) became dead).
    
    This drops the dead code, and deduplicates the rest.
    
    Change-Id: I0f7bbf8220792fbe42178c2689a065b5f38645d6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180069
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/include/systools/win32/wait_for_multiple_objects.hxx 
b/include/systools/win32/wait_for_multiple_objects.hxx
new file mode 100644
index 000000000000..bcffe7013d8b
--- /dev/null
+++ b/include/systools/win32/wait_for_multiple_objects.hxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <prewin.h>
+#include <objbase.h>
+#include <postwin.h>
+
+namespace sal::systools
+{
+/* Like WaitForMultipleObjects function, but makes sure to process COM 
messages during the wait,
+ * allowing other threads access to COM objects instantiated in this thread.
+ */
+DWORD WaitForMultipleObjects_COMDispatch(DWORD count, const HANDLE* handles, 
DWORD timeout)
+{
+    DWORD dwResult;
+    HRESULT hr = CoWaitForMultipleHandles(COWAIT_DISPATCH_CALLS, timeout, 
count,
+                                          const_cast<LPHANDLE>(handles), 
&dwResult);
+    if (hr == RPC_S_CALLPENDING)
+        return WAIT_TIMEOUT;
+    if (FAILED(hr))
+        return WAIT_FAILED;
+
+    return dwResult;
+}
+} // sal::systools
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sal/osl/w32/conditn.cxx b/sal/osl/w32/conditn.cxx
index 0ad233ed9bff..9063899533c3 100644
--- a/sal/osl/w32/conditn.cxx
+++ b/sal/osl/w32/conditn.cxx
@@ -22,6 +22,7 @@
 #include <osl/conditn.h>
 #include <osl/diagnose.h>
 #include <osl/time.h>
+#include <systools/win32/wait_for_multiple_objects.hxx>
 
 /*
     under WIN32, we use the void* oslCondition
@@ -75,39 +76,17 @@ oslConditionResult SAL_CALL osl_waitCondition(oslCondition 
Condition,
 
     /* It's necessary to process SendMessage calls to the current thread to 
give other threads
         access to COM objects instantiated in this thread */
-
-    while ( true )
+    switch (sal::systools::WaitForMultipleObjects_COMDispatch(
+        1, reinterpret_cast<HANDLE*>(&Condition), timeout))
     {
-        DWORD index;
-        /* Only wake up if a SendMessage / COM call to the threads message 
loop is detected */
-        HRESULT hr = CoWaitForMultipleHandles(COWAIT_DISPATCH_CALLS, timeout, 
1,
-                                              
reinterpret_cast<HANDLE*>(&Condition), &index);
-        if (hr == RPC_S_CALLPENDING)
-            return osl_cond_result_timeout;
-        if (FAILED(hr))
-            return osl_cond_result_error;
-        switch (index)
-        {
-            case WAIT_OBJECT_0 + 1:
-                {
-                MSG msg;
-
-                /* We Must not dispatch the message. PM_NOREMOVE leaves the 
message queue untouched
-                 but dispatches SendMessage calls automatically */
+        case WAIT_OBJECT_0:
+            return osl_cond_result_ok;
 
-                PeekMessageW( &msg, nullptr, 0, 0, PM_NOREMOVE );
-                }
-                break;
-
-            case WAIT_OBJECT_0:
-                return osl_cond_result_ok;
-
-            case WAIT_TIMEOUT:
-                return osl_cond_result_timeout;
+        case WAIT_TIMEOUT:
+            return osl_cond_result_timeout;
 
-            default:
-                return osl_cond_result_error;
-        }
+        default:
+            return osl_cond_result_error;
     }
 }
 
diff --git a/vcl/win/dtrans/MtaOleClipb.cxx b/vcl/win/dtrans/MtaOleClipb.cxx
index b671578f5b45..98c9d1ac578e 100644
--- a/vcl/win/dtrans/MtaOleClipb.cxx
+++ b/vcl/win/dtrans/MtaOleClipb.cxx
@@ -45,6 +45,7 @@
 
 #include <systools/win32/comtools.hxx>
 #include <systools/win32/retry_if_failed.hxx>
+#include <systools/win32/wait_for_multiple_objects.hxx>
 
 #include <comphelper/windowserrorstring.hxx>
 
@@ -67,8 +68,6 @@ namespace /* private */
     const bool INIT_NONSIGNALED = false;
 
     /*  Similar to osl conditions, with two condition objects passed to the 
Wait function.
-        COM Proxy-Stub communication uses SendMessages for
-        synchronization purposes.
     */
     class Win32Condition
     {
@@ -81,37 +80,15 @@ namespace /* private */
         // leave messages sent through
         bool wait(HANDLE hEvtAbort)
         {
-            HANDLE hWaitArray[2] = { m_hEvent, hEvtAbort };
-            while (true)
+            const HANDLE hWaitArray[2] = { m_hEvent, hEvtAbort };
+            switch (sal::systools::WaitForMultipleObjects_COMDispatch(2, 
hWaitArray, INFINITE))
             {
-                DWORD dwResult;
-                HRESULT hr = CoWaitForMultipleHandles(COWAIT_DISPATCH_CALLS, 
INFINITE, 2,
-                                                      hWaitArray, &dwResult);
-                if (FAILED(hr))
-                    return false;
-
-                switch (dwResult)
-                {
                     case WAIT_OBJECT_0: // wait successful
                         return true;
 
                     case WAIT_OBJECT_0 + 1: // wait aborted
-                        return false;
-
-                    case WAIT_OBJECT_0 + 2:
-                    {
-                        /* PeekMessage processes all messages in the 
SendMessage
-                           queue that's what we want, messages from the 
PostMessage
-                           queue stay untouched */
-                        MSG msg;
-                        PeekMessageW(&msg, nullptr, 0, 0, PM_NOREMOVE);
-
-                        break;
-                    }
-
                     default: // WAIT_FAILED?
                         return false;
-                }
             }
         }
 

Reply via email to