Alexandre Julliard : server: Use a standard user APC also for timers.
Alexandre Julliard
julliard at winehq.org
Tue May 25 16:08:15 CDT 2021
Module: wine
Branch: master
Commit: e1716530d92611026f84622546a596dc7a7d21d5
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e1716530d92611026f84622546a596dc7a7d21d5
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue May 25 13:03:49 2021 +0200
server: Use a standard user APC also for timers.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/server.c | 32 ++++++++++----------------------
dlls/ntdll/unix/thread.c | 10 +++++-----
include/wine/server_protocol.h | 25 ++++++-------------------
server/async.c | 10 +++++-----
server/protocol.def | 23 +++++------------------
server/thread.c | 1 -
server/timer.c | 11 ++++++-----
server/trace.c | 12 ++++--------
8 files changed, 41 insertions(+), 83 deletions(-)
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 );
More information about the wine-cvs
mailing list