Zebediah Figura : server: Use a separate function and flag to communicate that the initial status of an async is not known yet.

Alexandre Julliard julliard at winehq.org
Fri Sep 3 16:25:29 CDT 2021


Module: wine
Branch: master
Commit: dd58bf9ce236092a584b08e33c0cd16dd0a2e564
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=dd58bf9ce236092a584b08e33c0cd16dd0a2e564

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Sep  2 19:08:46 2021 -0500

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 <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 );




More information about the wine-cvs mailing list