Jacek Caban : server: Introduce a separated type for user APCs.

Alexandre Julliard julliard at winehq.org
Mon Apr 13 15:05:56 CDT 2020


Module: wine
Branch: master
Commit: 4f9cc93108a0ee2e589021319b4634869fff4517
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4f9cc93108a0ee2e589021319b4634869fff4517

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Apr 10 01:05:04 2020 +0200

server: Introduce a separated type for user APCs.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 d6b9b2ff0a..05f10769a5 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/include/wine/server_protocol.h b/include/wine/server_protocol.h
index ba3045be62..298e2dbfa4 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 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 93b558cc2b..bfe817b654 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 c1269e0ff0..6460acbf51 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 46c433e7a1..095a45f0dd 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 );




More information about the wine-cvs mailing list