If the SMTO_ABORTIFHUNG flag is set, periodically time out (every 1000ms) to check whether the thread from which a reply is expected has become hung while the sending thread has been waiting for that reply.
While it is the case that, when necessary, the wineserver checks whether a thread is hung before putting a message into its queue, this does not account for cases in which a thread becomes hung after that message has been enqueued but before it has been handled. In order to abort when hung in those cases, client code must perform this check itself.
Signed-off-by: Shawn M. Chapla schapla@codeweavers.com --- dlls/user32/message.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index a54ecccc7cd..6e988a6aeb0 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -2949,15 +2949,17 @@ static HANDLE get_server_queue_handle(void) * * Wait until a sent message gets replied to. */ -static void wait_message_reply( UINT flags ) +static void wait_message_reply( UINT flags, HWND hwnd ) { struct user_thread_info *thread_info = get_user_thread_info(); HANDLE server_queue = get_server_queue_handle(); unsigned int wake_mask = QS_SMRESULT | ((flags & SMTO_BLOCK) ? 0 : QS_SENDMESSAGE); + DWORD timeout = (flags & SMTO_ABORTIFHUNG) ? 1000 : INFINITE;
for (;;) { unsigned int wake_bits = 0; + DWORD ret = 0;
SERVER_START_REQ( set_queue_mask ) { @@ -2978,7 +2980,12 @@ static void wait_message_reply( UINT flags ) continue; }
- wow_handlers.wait_message( 1, &server_queue, INFINITE, wake_mask, 0 ); + ret = wow_handlers.wait_message( 1, &server_queue, timeout, wake_mask, 0 ); + + /* If the wait call timed out and the window we're waiting + on is now hung, bail. */ + if (ret == WAIT_TIMEOUT && IsHungAppWindow(hwnd)) + return; } }
@@ -3156,7 +3163,7 @@ static LRESULT send_inter_thread_message( const struct send_message_info *info, /* there's no reply to wait for on notify/callback messages */ if (info->type == MSG_NOTIFY || info->type == MSG_CALLBACK) return 1;
- wait_message_reply( info->flags ); + wait_message_reply( info->flags, info->hwnd ); return retrieve_reply( info, reply_size, res_ptr ); }
@@ -3309,7 +3316,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) if (wait) { LRESULT ignored; - wait_message_reply( 0 ); + wait_message_reply( 0, NULL ); retrieve_reply( &info, 0, &ignored ); } return ret;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=90083
Your paranoid android.
=== debiant2 (64 bit WoW report) ===
user32: win.c:10155: Test failed: Expected foreground window 0, got 0000000000F60050 win.c:10161: Test failed: Expected foreground window 00000000000E0120, got 0000000000F60050
On Fri, May 07, 2021 at 02:22:22PM -0400, Shawn M. Chapla wrote:
If the SMTO_ABORTIFHUNG flag is set, periodically time out (every 1000ms) to check whether the thread from which a reply is expected has become hung while the sending thread has been waiting for that reply.
My initial test code was not sufficiently rigorous and improving it has revealed that this patch is not correct. Please disregard it.