[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