From dd58bf9ce236092a584b08e33c0cd16dd0a2e564 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 2 Sep 2021 19:08:46 -0500 Subject: [PATCH] server: Use a separate function and flag to communicate that the initial status of an async is not known yet. Mostly just to simplify the interface, so that we don't need to use the return value to communicate this. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- server/async.c | 23 +++++++++++++++++------ server/device.c | 4 ++-- server/file.h | 1 + 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/server/async.c b/server/async.c index e8d95a62d4b..4e9f3253759 100644 --- a/server/async.c +++ b/server/async.c @@ -53,6 +53,7 @@ struct async unsigned int direct_result :1;/* a flag if we're passing result directly from request instead of APC */ unsigned int alerted :1; /* fd is signaled, but we are waiting for client-side I/O */ unsigned int terminated :1; /* async has been terminated */ + unsigned int unknown_status :1; /* initial status is not known yet */ struct completion *completion; /* completion associated with fd */ apc_param_t comp_key; /* completion key associated with fd */ unsigned int comp_flags; /* completion flags */ @@ -258,6 +259,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da async->direct_result = 0; async->alerted = 0; async->terminated = 0; + async->unknown_status = 0; async->completion = fd_get_completion( fd, &async->comp_key ); async->comp_flags = 0; async->completion_callback = NULL; @@ -284,6 +286,7 @@ void set_async_pending( struct async *async, int signal ) if (!async->terminated) { async->pending = 1; + async->unknown_status = 0; if (signal && !async->signaled) { async->signaled = 1; @@ -295,14 +298,15 @@ void set_async_pending( struct async *async, int signal ) /* return async object status and wait handle to client */ obj_handle_t async_handoff( struct async *async, int success, data_size_t *result, int force_blocking ) { + if (async->unknown_status) + { + /* even the initial status is not known yet */ + set_error( STATUS_PENDING ); + return async->wait_handle; + } + if (!success) { - if (get_error() == STATUS_PENDING) - { - /* we don't know the result yet, so client needs to wait */ - async->direct_result = 0; - return async->wait_handle; - } close_handle( async->thread->process, async->wait_handle ); async->wait_handle = 0; return 0; @@ -381,6 +385,13 @@ void async_request_complete_alloc( struct async *async, unsigned int status, dat async_request_complete( async, status, result, out_size, out_data_copy ); } +/* mark an async as having unknown initial status */ +void async_set_unknown_status( struct async *async ) +{ + async->unknown_status = 1; + async->direct_result = 0; +} + /* set the timeout of an async operation */ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ) { diff --git a/server/device.c b/server/device.c index 29b36845e68..8892651d048 100644 --- a/server/device.c +++ b/server/device.c @@ -605,8 +605,8 @@ static int queue_irp( struct device_file *file, const irp_params_t *params, stru irp->async = (struct async *)grab_object( async ); add_irp_to_queue( file->device->manager, irp, current ); release_object( irp ); - set_error( STATUS_PENDING ); - return 0; + async_set_unknown_status( async ); + return 1; } static enum server_fd_type device_file_get_fd_type( struct fd *fd ) diff --git a/server/file.h b/server/file.h index 8e42cd3704e..9b8a620359e 100644 --- a/server/file.h +++ b/server/file.h @@ -224,6 +224,7 @@ extern void queue_async( struct async_queue *queue, struct async *async ); extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ); extern void async_set_result( struct object *obj, unsigned int status, apc_param_t total ); extern void async_set_completion_callback( struct async *async, async_completion_callback func, void *private ); +extern void async_set_unknown_status( struct async *async ); extern void set_async_pending( struct async *async, int signal ); extern int async_waiting( struct async_queue *queue ); extern void async_terminate( struct async *async, unsigned int status );