From 2dc99bfb308393f95d6d9896e030646012beddf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Wed, 5 Feb 2020 11:49:39 +0100 Subject: [PATCH] ntdll: Handle system APCs in a separate inner loop. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/ntdll/server.c | 39 ++++++++++++++++++++++----------------- dlls/ntdll/sync.c | 31 ++++++++++++++++++------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index c17ab964d5d..15d53b348ef 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -606,26 +606,31 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT do { - SERVER_START_REQ( select ) + for (;;) { - req->flags = flags; - req->cookie = wine_server_client_ptr( &cookie ); - req->prev_apc = apc_handle; - req->timeout = abs_timeout; - wine_server_add_data( req, &result, sizeof(result) ); - wine_server_add_data( req, select_op, size ); - ret = wine_server_call( req ); - abs_timeout = reply->timeout; - apc_handle = reply->apc_handle; - call = reply->call; + SERVER_START_REQ( select ) + { + req->flags = flags; + req->cookie = wine_server_client_ptr( &cookie ); + req->prev_apc = apc_handle; + req->timeout = abs_timeout; + wine_server_add_data( req, &result, sizeof(result) ); + wine_server_add_data( req, select_op, size ); + ret = wine_server_call( req ); + abs_timeout = reply->timeout; + apc_handle = reply->apc_handle; + call = reply->call; + } + SERVER_END_REQ; + + /* don't signal multiple times */ + if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT) + size = offsetof( select_op_t, signal_and_wait.signal ); + + if (ret != STATUS_KERNEL_APC) break; + invoke_apc( &call, &result ); } - SERVER_END_REQ; - /* don't signal multiple times */ - if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT) - size = offsetof( select_op_t, signal_and_wait.signal ); - - if (ret == STATUS_KERNEL_APC) invoke_apc( &call, &result ); if (ret == STATUS_USER_APC) { invoke_apc( &call, &result ); diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 3e670f47f78..8b12e03eeff 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -2479,24 +2479,29 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size return STATUS_SUCCESS; } - SERVER_START_REQ( select ) + for (;;) { - req->flags = SELECT_INTERRUPTIBLE; - req->cookie = wine_server_client_ptr( &cookie ); - req->prev_apc = apc_handle; - req->timeout = abs_timeout; - wine_server_add_data( req, &result, sizeof(result) ); - wine_server_add_data( req, &select_op, sizeof(select_op.keyed_event) ); - ret = wine_server_call( req ); - abs_timeout = reply->timeout; - apc_handle = reply->apc_handle; - call = reply->call; + SERVER_START_REQ( select ) + { + req->flags = SELECT_INTERRUPTIBLE; + req->cookie = wine_server_client_ptr( &cookie ); + req->prev_apc = apc_handle; + req->timeout = abs_timeout; + wine_server_add_data( req, &result, sizeof(result) ); + wine_server_add_data( req, &select_op, sizeof(select_op.keyed_event) ); + ret = wine_server_call( req ); + abs_timeout = reply->timeout; + apc_handle = reply->apc_handle; + call = reply->call; + } + SERVER_END_REQ; + + if (ret != STATUS_KERNEL_APC) break; + invoke_apc( &call, &result ); } - SERVER_END_REQ; RtlLeaveCriticalSection( &addr_section ); - if (ret == STATUS_KERNEL_APC) invoke_apc( &call, &result ); if (ret == STATUS_USER_APC) { invoke_apc( &call, &result );