From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/message.c | 24 ++++++++++++++++++++---- dlls/win32u/ntuser_private.h | 1 - 2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 3a3f79a2ee8..f0c06ae8eeb 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -27,6 +27,8 @@ #include <assert.h> #include "ntstatus.h" #define WIN32_NO_STATUS +#include "winternl.h" +#include "ddk/wdm.h" #include "win32u_private.h" #include "ntuser_private.h" #include "winnls.h" @@ -40,6 +42,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(msg); WINE_DECLARE_DEBUG_CHANNEL(key); WINE_DECLARE_DEBUG_CHANNEL(relay);
+static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000; + +static UINT64 get_tick_count(void) +{ + ULONG high, low; + + do + { + high = user_shared_data->TickCount.High1Time; + low = user_shared_data->TickCount.LowPart; + } + while (high != user_shared_data->TickCount.High2Time); + /* note: we ignore TickCountMultiplier */ + return (UINT64)high << 32 | low; +} + #define MAX_WINPROC_RECURSION 64
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE @@ -2767,7 +2785,7 @@ static BOOL check_queue_bits( UINT wake_mask, UINT changed_mask, UINT signal_bit { *wake_bits = queue_shm->wake_bits; *changed_bits = queue_shm->changed_bits; - skip = TRUE; + skip = get_tick_count() - (UINT64)queue_shm->access_time / 10000 < 3000; /* avoid hung queue */ } }
@@ -2822,8 +2840,7 @@ int peek_message( MSG *msg, const struct peek_message_filter *filter ) thread_info->client_info.msg_source = prev_source; wake_mask = filter->mask & (QS_SENDMESSAGE | QS_SMRESULT);
- if (NtGetTickCount() - thread_info->last_getmsg_time < 3000 && /* avoid hung queue */ - check_queue_bits( wake_mask, filter->mask, wake_mask | signal_bits, filter->mask | clear_bits, + if (check_queue_bits( wake_mask, filter->mask, wake_mask | signal_bits, filter->mask | clear_bits, &wake_bits, &changed_bits )) res = STATUS_PENDING; else SERVER_START_REQ( get_message ) @@ -2837,7 +2854,6 @@ int peek_message( MSG *msg, const struct peek_message_filter *filter ) req->wake_mask = wake_mask; req->changed_mask = filter->mask; wine_server_set_reply( req, buffer, buffer_size ); - thread_info->last_getmsg_time = NtGetTickCount(); if (!(res = wine_server_call( req ))) { size = wine_server_reply_size( reply ); diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 643a01c6fba..2de11465f87 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -102,7 +102,6 @@ struct user_thread_info { struct ntuser_thread_info client_info; /* Data shared with client */ HANDLE server_queue; /* Handle to server-side queue */ - DWORD last_getmsg_time; /* Get/PeekMessage last request time */ LONGLONG last_driver_time; /* Get/PeekMessage driver event time */ WORD hook_call_depth; /* Number of recursively called hook procs */ WORD hook_unicode; /* Is current hook unicode? */