[PATCH 1/9] server: Use a separate function and flag to communicate that the initial status of an async is not known yet.

Zebediah Figura zfigura at codeweavers.com
Thu Sep 2 19:08:46 CDT 2021


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 <zfigura at codeweavers.com>
---
 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 );
-- 
2.33.0




More information about the wine-devel mailing list