From 4f9cc93108a0ee2e589021319b4634869fff4517 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 10 Apr 2020 01:05:04 +0200 Subject: [PATCH] server: Introduce a separated type for user APCs. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/ntdll/server.c | 34 ++++++++++++++++++++++++---------- dlls/ntdll/thread.c | 10 +++++----- include/wine/server_protocol.h | 8 +++++++- server/async.c | 10 +++++----- server/protocol.def | 6 ++++++ server/timer.c | 8 ++++---- server/trace.c | 12 ++++++------ 7 files changed, 57 insertions(+), 31 deletions(-) diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index d6b9b2ff0ab..05f10769a5c 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 6baeb610fc4..ee3c925f916 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/include/wine/server_protocol.h b/include/wine/server_protocol.h index ba3045be62f..298e2dbfa4a 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -474,6 +474,12 @@ typedef union abstime_t time; client_ptr_t arg; } timer; +} user_apc_t; + +typedef union +{ + enum apc_type type; + user_apc_t user; struct { enum apc_type type; @@ -6710,7 +6716,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 597 +#define SERVER_PROTOCOL_VERSION 598 /* ### protocol_version end ### */ diff --git a/server/async.c b/server/async.c index 5486601c675..03994e8fac2 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 93b558cc2b4..bfe817b6543 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -490,6 +490,12 @@ typedef union abstime_t time; /* 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 c1269e0ff01..6460acbf519 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 */ diff --git a/server/trace.c b/server/trace.c index 46c433e7a1d..095a45f0dd5 100644 --- a/server/trace.c +++ b/server/trace.c @@ -159,15 +159,15 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call ) fprintf( stderr, "APC_NONE" ); break; case APC_USER: - dump_uint64( "APC_USER,func=", &call->user.func ); - dump_uint64( ",args={", &call->user.args[0] ); - dump_uint64( ",", &call->user.args[1] ); - dump_uint64( ",", &call->user.args[2] ); + dump_uint64( "APC_USER,func=", &call->user.user.func ); + dump_uint64( ",args={", &call->user.user.args[0] ); + dump_uint64( ",", &call->user.user.args[1] ); + dump_uint64( ",", &call->user.user.args[2] ); fputc( '}', stderr ); break; case APC_TIMER: - dump_timeout( "APC_TIMER,time=", &call->timer.time ); - dump_uint64( ",arg=", &call->timer.arg ); + dump_timeout( "APC_TIMER,time=", &call->user.timer.time ); + dump_uint64( ",arg=", &call->user.timer.arg ); break; case APC_ASYNC_IO: dump_uint64( "APC_ASYNC_IO,user=", &call->async_io.user );