diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 10f53bea8ab..ca712e4a56c 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -351,30 +351,18 @@ static int wait_select_reply( void *cookie ) } -static void invoke_apc( CONTEXT *context, const user_apc_t *apc ) +/*********************************************************************** + * invoke_user_apc + */ +static void invoke_user_apc( CONTEXT *context, const user_apc_t *apc ) { - switch( apc->type ) - { - case APC_USER: - call_user_apc_dispatcher( context, apc->user.args[0], apc->user.args[1], apc->user.args[2], - wine_server_get_ptr( apc->user.func ), pKiUserApcDispatcher ); - break; - case APC_TIMER: - call_user_apc_dispatcher( context, (ULONG_PTR)wine_server_get_ptr( apc->user.args[1] ), - (DWORD)apc->timer.time, (DWORD)(apc->timer.time >> 32), - wine_server_get_ptr( apc->user.func ), pKiUserApcDispatcher ); - break; - default: - server_protocol_error( "get_apc_request: bad type %d\n", apc->type ); - break; - } + call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2], + wine_server_get_ptr( apc->func ), pKiUserApcDispatcher ); } + /*********************************************************************** - * invoke_apc - * - * Invoke a single APC. - * + * invoke_system_apc */ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self ) { @@ -702,7 +690,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f } ret = server_select( select_op, size, flags, abs_timeout, NULL, NULL, &apc ); - if (ret == STATUS_USER_APC) invoke_apc( NULL, &apc ); + if (ret == STATUS_USER_APC) invoke_user_apc( NULL, &apc ); /* A test on Windows 2000 shows that Windows always yields during a wait, but a wait that is hit by an event gets a priority @@ -723,7 +711,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable ) if (alertable) { status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, NULL, &apc ); - if (status == STATUS_USER_APC) invoke_apc( context, &apc ); + if (status == STATUS_USER_APC) invoke_user_apc( context, &apc ); } status = NtSetContextThread( GetCurrentThread(), context ); if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 1ac87352b39..54b748e99cb 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1296,11 +1296,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.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; + 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; } 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 e48154fb120..730bb3c151c 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -455,7 +455,6 @@ enum apc_type { APC_NONE, APC_USER, - APC_TIMER, APC_ASYNC_IO, APC_VIRTUAL_ALLOC, APC_VIRTUAL_FREE, @@ -471,24 +470,12 @@ enum apc_type APC_BREAK_PROCESS }; -typedef union +typedef struct { - enum apc_type type; - struct - { - enum apc_type type; - int __pad; - client_ptr_t func; - apc_param_t args[3]; - } user; - struct - { - enum apc_type type; - int __pad; - client_ptr_t func; - abstime_t time; - client_ptr_t arg; - } timer; + enum apc_type type; + int __pad; + client_ptr_t func; + apc_param_t args[3]; } user_apc_t; typedef union @@ -6300,7 +6287,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 705 +#define SERVER_PROTOCOL_VERSION 706 /* ### protocol_version end ### */ diff --git a/server/async.c b/server/async.c index 27af3be52ff..d6d3a8ad86a 100644 --- a/server/async.c +++ b/server/async.c @@ -406,11 +406,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.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; + 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; 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 db50e03c691..f0a9107cfbe 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -471,7 +471,6 @@ enum apc_type { APC_NONE, APC_USER, - APC_TIMER, APC_ASYNC_IO, APC_VIRTUAL_ALLOC, APC_VIRTUAL_FREE, @@ -487,24 +486,12 @@ enum apc_type APC_BREAK_PROCESS }; -typedef union +typedef struct { - enum apc_type type; - struct - { - enum apc_type type; /* APC_USER */ - int __pad; - client_ptr_t func; /* void (__stdcall *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR); */ - apc_param_t args[3]; /* arguments for user function */ - } user; - struct - { - enum apc_type type; /* APC_TIMER */ - int __pad; - client_ptr_t func; /* void (__stdcall *func)(void*, unsigned int, unsigned int); */ - abstime_t time; /* time of expiration */ - client_ptr_t arg; /* user argument */ - } timer; + enum apc_type type; /* APC_USER */ + int __pad; + client_ptr_t func; /* void (__stdcall *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR); */ + apc_param_t args[3]; /* arguments for user function */ } user_apc_t; typedef union diff --git a/server/thread.c b/server/thread.c index 4077a752e4a..0c7f11c0da1 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1071,7 +1071,6 @@ static inline struct list *get_apc_queue( struct thread *thread, enum apc_type t case APC_NONE: return NULL; case APC_USER: - case APC_TIMER: return &thread->user_apc; default: return &thread->system_apc; diff --git a/server/timer.c b/server/timer.c index 0c787d0b7e0..5e265d2ddf6 100644 --- a/server/timer.c +++ b/server/timer.c @@ -128,10 +128,11 @@ static void timer_callback( void *private ) assert (timer->callback); memset( &data, 0, sizeof(data) ); - data.type = APC_TIMER; - data.user.timer.func = timer->callback; - data.user.timer.time = timer->when; - data.user.timer.arg = timer->arg; + data.type = APC_USER; + data.user.func = timer->callback; + data.user.args[0] = timer->arg; + data.user.args[1] = (unsigned int)timer->when; + data.user.args[2] = timer->when >> 32; if (!thread_queue_apc( NULL, timer->thread, &timer->obj, &data )) { @@ -165,7 +166,7 @@ static int cancel_timer( struct timer *timer ) } if (timer->thread) { - thread_cancel_apc( timer->thread, &timer->obj, APC_TIMER ); + thread_cancel_apc( timer->thread, &timer->obj, APC_USER ); release_object( timer->thread ); timer->thread = NULL; } diff --git a/server/trace.c b/server/trace.c index d9ca82bd228..1420f1e799f 100644 --- a/server/trace.c +++ b/server/trace.c @@ -156,16 +156,12 @@ 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.user.func ); - dump_uint64( ",args={", &call->user.user.args[0] ); - dump_uint64( ",", &call->user.user.args[1] ); - dump_uint64( ",", &call->user.user.args[2] ); + 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] ); fputc( '}', stderr ); break; - case APC_TIMER: - 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 ); dump_uint64( ",sb=", &call->async_io.sb );