[PATCH 4/5] ntdll: Handle system APCs in a separate inner loop.
Rémi Bernon
rbernon at codeweavers.com
Tue Feb 4 04:09:24 CST 2020
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
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 ca7ee166a3d..0716398e58e 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
for (;;)
{
- 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_END_REQ;
+ 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 );
- /* 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 );
+ }
- 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 8ec05103675..41fcf498d09 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 );
--
2.25.0
More information about the wine-devel
mailing list