[RFC PATCH v2 06/11] server: Prevent I/O synchronous completion requests from firing APC interrupts if possible.

Jinoh Kang jinoh.kang.kr at gmail.com
Sat Jan 22 08:36:44 CST 2022


Synchronously deliver the pending system APC via server call reply if
possible, instead of interrupting the target thread with a signal.

Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---

Notes:
    Alternative approaches considered:
    
    1. Don't use thread_queue_apc to deliver the pseudo-APC; instead, use create_apc
       directly.  In this case, this would shorten this patch a lot, but would
       transfer the complexity of this patch to the previous one in the serie.
    
    2. Don't use APC at all (the previous patch).  In this case we do not create
       APCs at all, and this patch becomes unnecessary.

 server/async.c      |  1 +
 server/protocol.def |  1 +
 server/sock.c       | 10 ++++++++++
 server/trace.c      |  3 ---
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/server/async.c b/server/async.c
index 5d0857f3eec..cf49a309da6 100644
--- a/server/async.c
+++ b/server/async.c
@@ -396,6 +396,7 @@ void async_start_sync_io_request( struct async *async, data_size_t information )
     assert( async->thread == current );
     assert( !async->pending );
 
+    try_suspend_apc_interrupt();
     async->direct_result = 0;  /* force APC to fire off */
     async->iosb->result = information;
 }
diff --git a/server/protocol.def b/server/protocol.def
index f21f7187c4d..348791c28da 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1447,6 +1447,7 @@ enum server_fd_type
 @REPLY
     obj_handle_t wait;          /* handle to wait on for blocking recv */
     unsigned int options;       /* device open options */
+    VARARG(inline_apc,inline_apc); /* Next system APC to execute immediately */
 @END
 
 
diff --git a/server/sock.c b/server/sock.c
index 03c867317b2..683cbb21aa6 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -3470,6 +3470,16 @@ DECL_HANDLER(recv_socket)
 
         reply->wait = async_handoff( async, NULL, 0 );
         reply->options = get_fd_options( fd );
+
+        if (status == STATUS_ALERTED)
+        {
+            inline_apc_t inline_apc;
+            if (get_reply_max_size() == sizeof(inline_apc) && dequeue_synchronous_system_apc( &inline_apc ))
+                set_reply_data( &inline_apc, sizeof(inline_apc) );
+            else
+                resume_apc_interrupt();
+        }
+
         release_object( async );
     }
     release_object( sock );
diff --git a/server/trace.c b/server/trace.c
index 7a6f5e1c119..40aa1078cf2 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -540,9 +540,6 @@ static void dump_varargs_apc_result( const char *prefix, data_size_t size )
     remove_data( size );
 }
 
-#ifdef __GNUC__
-__attribute__((unused))
-#endif
 static void dump_varargs_inline_apc( const char *prefix, data_size_t size )
 {
     const inline_apc_t *result = cur_data;
-- 
2.31.1




More information about the wine-devel mailing list