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@gmail.com --- dlls/ole32/compobj.c | 10 ++++++++++ dlls/ole32/tests/compobj.c | 20 ++++++++++++++++++++ 2 files changed, 30 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..127f387e4a 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; @@ -2854,6 +2873,7 @@ static void test_CoWaitForMultipleHandles(void) success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
+ index = 0xdeadbeef; PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_NOREMOVE);
On Wed, Jan 10, 2018 at 10:00:29PM -0800, Anton Romanov wrote:
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@gmail.com
This looks good and should go in after Wine 3.0. Could you please re-submit with the commit log changed [ole32] -> ole32: and remove the white-space change that is the final hunk.
Huw.
dlls/ole32/compobj.c | 10 ++++++++++ dlls/ole32/tests/compobj.c | 20 ++++++++++++++++++++ 2 files changed, 30 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..127f387e4a 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;
@@ -2854,6 +2873,7 @@ static void test_CoWaitForMultipleHandles(void) success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
- index = 0xdeadbeef; PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_NOREMOVE);
-- 2.15.1
On Thu, Jan 18, 2018 at 1:51 AM, Huw Davies huw@codeweavers.com wrote:
On Wed, Jan 10, 2018 at 10:00:29PM -0800, Anton Romanov wrote:
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@gmail.com
This looks good and should go in after Wine 3.0. Could you please re-submit with the commit log changed [ole32] -> ole32: and remove the white-space change that is the final hunk.
Thanks, re-submitted.