From: Jacek Caban Subject: [PATCH 1/5] server: Introduce separated type for user APCs. Message-Id: <988a1094-866a-cfe2-58a5-7fff8fe67fcf@codeweavers.com> Date: Wed, 8 Apr 2020 20:26:49 +0200 Signed-off-by: Jacek Caban --- dlls/ntdll/server.c | 34 ++++++++++++++++++++++++---------- dlls/ntdll/thread.c | 10 +++++----- server/async.c | 10 +++++----- server/protocol.def | 6 ++++++ server/timer.c | 8 ++++---- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index df847d09a2..dc9e5ea165 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -381,6 +381,29 @@ int wait_select_reply( void *cookie ) } +static void invoke_user_apc( const user_apc_t *apc ) +{ + switch( apc->type ) + { + case APC_USER: + { + void (WINAPI *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR) = wine_server_get_ptr( apc->user.func ); + func( apc->user.args[0], apc->user.args[1], apc->user.args[2] ); + break; + } + case APC_TIMER: + { + void (WINAPI *func)(void*, unsigned int, unsigned int) = wine_server_get_ptr( apc->user.func ); + func( wine_server_get_ptr( apc->user.args[1] ), + (DWORD)apc->timer.time, (DWORD)(apc->timer.time >> 32) ); + break; + } + default: + server_protocol_error( "get_apc_request: bad type %d\n", apc->type ); + break; + } +} + /*********************************************************************** * invoke_apc * @@ -400,18 +423,9 @@ void invoke_apc( const apc_call_t *call, apc_result_t *result ) case APC_NONE: break; case APC_USER: - { - void (WINAPI *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR) = wine_server_get_ptr( call->user.func ); - func( call->user.args[0], call->user.args[1], call->user.args[2] ); - break; - } case APC_TIMER: - { - void (WINAPI *func)(void*, unsigned int, unsigned int) = wine_server_get_ptr( call->timer.func ); - func( wine_server_get_ptr( call->timer.arg ), - (DWORD)call->timer.time, (DWORD)(call->timer.time >> 32) ); + invoke_user_apc( &call->user ); break; - } case APC_ASYNC_IO: { IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb ); diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 6baeb610fc..ee3c925f91 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -739,11 +739,11 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1 req->handle = wine_server_obj_handle( handle ); if (func) { - req->call.type = APC_USER; - req->call.user.func = wine_server_client_ptr( func ); - req->call.user.args[0] = arg1; - req->call.user.args[1] = arg2; - req->call.user.args[2] = arg3; + req->call.type = APC_USER; + req->call.user.user.func = wine_server_client_ptr( func ); + req->call.user.user.args[0] = arg1; + req->call.user.user.args[1] = arg2; + req->call.user.user.args[2] = arg3; } else req->call.type = APC_NONE; /* wake up only */ ret = wine_server_call( req ); diff --git a/server/async.c b/server/async.c index 5486601c67..03994e8fac 100644 --- a/server/async.c +++ b/server/async.c @@ -399,11 +399,11 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota { apc_call_t data; memset( &data, 0, sizeof(data) ); - data.type = APC_USER; - data.user.func = async->data.apc; - data.user.args[0] = async->data.apc_context; - data.user.args[1] = async->data.iosb; - data.user.args[2] = 0; + data.type = APC_USER; + data.user.user.func = async->data.apc; + data.user.user.args[0] = async->data.apc_context; + data.user.user.args[1] = async->data.iosb; + data.user.user.args[2] = 0; thread_queue_apc( NULL, async->thread, NULL, &data ); } else if (async->data.apc_context && (async->pending || diff --git a/server/protocol.def b/server/protocol.def index 722993e59c..cab52d4a2e 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -487,6 +487,12 @@ typedef union timeout_t time; /* absolute time of expiration */ client_ptr_t arg; /* user argument */ } timer; +} user_apc_t; + +typedef union +{ + enum apc_type type; + user_apc_t user; struct { enum apc_type type; /* APC_ASYNC_IO */ diff --git a/server/timer.c b/server/timer.c index 9cca85569f..37a2048b45 100644 --- a/server/timer.c +++ b/server/timer.c @@ -116,10 +116,10 @@ static void timer_callback( void *private ) memset( &data, 0, sizeof(data) ); if (timer->callback) { - data.type = APC_TIMER; - data.timer.func = timer->callback; - data.timer.time = timer->when; - data.timer.arg = timer->arg; + data.type = APC_TIMER; + data.user.timer.func = timer->callback; + data.user.timer.time = timer->when; + data.user.timer.arg = timer->arg; } else data.type = APC_NONE; /* wake up only */