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