[PATCH v7 03/11] server: Ensure async completion callback is called on synchronous failure.

Jinoh Kang jinoh.kang.kr at gmail.com
Sat Mar 19 17:28:08 CDT 2022


async_set_result() is the only way the async completion callback can be
called.  If the async were a request async and the I/O failed even
before it was marked as pending, async_handoff() simply discards the
async without either calling async_set_result() or directly invoking the
completion callback.  This leads to memory leak.

Fix this by calling the completion_callback on synchronous failure path
if it was not already called, setting it to NULL afterwards.

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

Notes:
    v6 -> v7: new patch

 server/async.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/server/async.c b/server/async.c
index d49fb8b7c04..182344923d4 100644
--- a/server/async.c
+++ b/server/async.c
@@ -322,6 +322,13 @@ void async_wake_obj( struct async *async )
     }
 }
 
+static void async_call_completion_callback( struct async *async )
+{
+    if (async->completion_callback)
+        async->completion_callback( async->completion_callback_private );
+    async->completion_callback = NULL;
+}
+
 /* return async object status and wait handle to client */
 obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_blocking )
 {
@@ -363,6 +370,8 @@ obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_
 
     if (!async->pending && NT_ERROR( get_error() ))
     {
+        async_call_completion_callback( async );
+
         close_handle( async->thread->process, async->wait_handle );
         async->wait_handle = 0;
         return 0;
@@ -528,9 +537,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
             wake_up( &async->obj, 0 );
         }
 
-        if (async->completion_callback)
-            async->completion_callback( async->completion_callback_private );
-        async->completion_callback = NULL;
+        async_call_completion_callback( async );
 
         if (async->queue)
         {
-- 
2.34.1




More information about the wine-devel mailing list