[PATCH v2] ole32: Make CoWaitForMultipleHandles peek at all posted messages
Anton Romanov
theli.ua at gmail.com
Fri Jan 19 00:17:06 CST 2018
Fixes https://bugs.winehq.org/show_bug.cgi?id=43728
This matches Windows behaviour and also avoids making
CoWaitForMultipleHandles's message_loop constantly spin because of
unpeeked/unpumped message in the queue
Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---
dlls/ole32/compobj.c | 10 ++++++++++
dlls/ole32/tests/compobj.c | 19 +++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index d136ee623a..48030aee71 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -4547,6 +4547,16 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
}
}
+ if (!apt->win)
+ {
+ /* If window is NULL on apartment we don't pump every
+ * single POSTMESSAGE message. Windows doesn't either but it peeks at
+ * them so that it will not trigger
+ * MsgWaitForMultipleObjects next time.
+ * If we don't do this and happen to have a message that is
+ * not pumped below we end up in a tight loop */
+ PeekMessageW(NULL, NULL, 0, 0, PM_QS_POSTMESSAGE | PM_NOREMOVE | PM_NOYIELD);
+ }
/* some apps (e.g. Visio 2010) don't handle WM_PAINT properly and loop forever,
* so after processing 100 messages we go back to checking the wait handles */
while (count++ < 100 && COM_PeekMessage(apt, &msg))
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index b46ff03853..83595cb8a4 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -2648,7 +2648,9 @@ static DWORD CALLBACK test_CoWaitForMultipleHandles_thread(LPVOID arg)
DWORD index;
HRESULT hr;
HWND hWnd;
+ UINT uMSG = 0xc065;
MSG msg;
+ int ret;
hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
@@ -2672,6 +2674,23 @@ static DWORD CALLBACK test_CoWaitForMultipleHandles_thread(LPVOID arg)
success = PeekMessageA(&msg, hWnd, WM_USER, WM_USER, PM_REMOVE);
ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
+ /* Even if CoWaitForMultipleHandles does not pump a message it peeks
+ * at ALL of them */
+ index = 0xdeadbeef;
+ PostMessageA(NULL, uMSG, 0, 0);
+
+ hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index);
+ ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
+ ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
+
+ /* Make sure message was peeked at */
+ ret = MsgWaitForMultipleObjectsEx(0, NULL, 2, QS_ALLPOSTMESSAGE, MWMO_ALERTABLE);
+ ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %x\n", ret);
+
+ /* But not pumped */
+ success = PeekMessageA(&msg, NULL, uMSG, uMSG, PM_REMOVE);
+ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
+
DestroyWindow(hWnd);
CoUninitialize();
return 0;
--
2.15.1
More information about the wine-devel
mailing list