From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/message.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 6f16a1ddb41..d80b4f8104c 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3179,6 +3179,21 @@ static HANDLE get_server_queue_handle(void) return ret; }
+static BOOL is_queue_signaled(void) +{ + struct object_lock lock = OBJECT_LOCK_INIT; + const queue_shm_t *queue_shm; + BOOL signaled = FALSE; + UINT status; + + while ((status = get_shared_queue( &lock, &queue_shm )) == STATUS_PENDING) + signaled = (queue_shm->wake_bits & queue_shm->wake_mask) || + (queue_shm->changed_bits & queue_shm->changed_mask); + if (status) return FALSE; + + return signaled; +} + static BOOL check_internal_bits( UINT mask ) { struct object_lock lock = OBJECT_LOCK_INIT; @@ -3249,9 +3264,9 @@ static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DW { struct thunk_lock_params params = {.dispatch.callback = thunk_lock_callback}; LARGE_INTEGER time, now, *abs; - DWORD ret = count - 1; void *ret_ptr; ULONG ret_len; + DWORD ret;
if ((abs = get_nt_timeout( &time, timeout ))) { @@ -3269,13 +3284,13 @@ static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DW if (process_driver_events( QS_ALLINPUT )) ret = count - 1; else { - ret = NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), !!(flags & MWMO_ALERTABLE), abs ); - if (ret == count - 1) process_driver_events( QS_ALLINPUT ); - else if (HIWORD(ret)) /* is it an error code? */ - { - RtlSetLastWin32Error( RtlNtStatusToDosError(ret) ); - ret = WAIT_FAILED; - } + do ret = NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), !!(flags & MWMO_ALERTABLE), abs ); + while (ret == count - 1 && !process_driver_events( QS_ALLINPUT ) && !is_queue_signaled()); + } + if (HIWORD(ret)) /* is it an error code? */ + { + RtlSetLastWin32Error( RtlNtStatusToDosError(ret) ); + ret = WAIT_FAILED; }
if (ret == WAIT_TIMEOUT && !count && !timeout) NtYieldExecution();