[PATCH v7 07/11] server: Add mark_pending field to set_async_direct_result request.

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


The client can set mark_pending to indicate that the full-blown I/O
completion mechanism shall be triggered (asynchronous completion) even
if the status indicates failure.

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

Notes:
    v1 -> v2: no changes
    v2 -> v3: no changes
    v3 -> v4: no changes
    v4 -> v5: no changes
    v5 -> v6: no changes
    v6 -> v7: no changes

 dlls/ntdll/unix/socket.c       |  2 +-
 dlls/ntdll/unix/sync.c         |  9 +++++----
 dlls/ntdll/unix/unix_private.h |  2 +-
 server/async.c                 | 11 ++++++++---
 server/protocol.def            |  1 +
 5 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 23059e3cff8..2f8bd6e62bf 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -767,7 +767,7 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
         release_fileio( &async->io );
     }
 
-    if (alerted) set_async_direct_result( &wait_handle, status, information );
+    if (alerted) set_async_direct_result( &wait_handle, status, information, FALSE );
     if (wait_handle) status = wait_async( wait_handle, options & FILE_SYNCHRONOUS_IO_ALERT );
     return status;
 }
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index ee25dfd0099..0786454dad2 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -2514,7 +2514,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
 /* Notify direct completion of async and close the wait handle if it is no longer needed.
  * This function is a no-op (returns status as-is) if the supplied handle is NULL.
  */
-void set_async_direct_result( HANDLE *optional_handle, NTSTATUS status, ULONG_PTR information )
+void set_async_direct_result( HANDLE *optional_handle, NTSTATUS status, ULONG_PTR information, BOOL mark_pending )
 {
     NTSTATUS ret;
 
@@ -2522,9 +2522,10 @@ void set_async_direct_result( HANDLE *optional_handle, NTSTATUS status, ULONG_PT
 
     SERVER_START_REQ( set_async_direct_result )
     {
-        req->handle      = wine_server_obj_handle( *optional_handle );
-        req->status      = status;
-        req->information = information;
+        req->handle       = wine_server_obj_handle( *optional_handle );
+        req->status       = status;
+        req->information  = information;
+        req->mark_pending = mark_pending;
         ret = wine_server_call( req );
         if (ret == STATUS_SUCCESS)
             *optional_handle = wine_server_ptr_handle( reply->handle );
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index b1595c792c0..b1a834efba5 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -274,7 +274,7 @@ extern NTSTATUS get_device_info( int fd, struct _FILE_FS_DEVICE_INFORMATION *inf
 extern void init_files(void) DECLSPEC_HIDDEN;
 extern void init_cpu_info(void) DECLSPEC_HIDDEN;
 extern void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULONG info, BOOL async ) DECLSPEC_HIDDEN;
-extern void set_async_direct_result( HANDLE *optional_handle, NTSTATUS status, ULONG_PTR information );
+extern void set_async_direct_result( HANDLE *optional_handle, NTSTATUS status, ULONG_PTR information, BOOL mark_pending );
 
 extern void dbg_init(void) DECLSPEC_HIDDEN;
 
diff --git a/server/async.c b/server/async.c
index 6905058fa69..a4fbeab555e 100644
--- a/server/async.c
+++ b/server/async.c
@@ -780,10 +780,15 @@ DECL_HANDLER(set_async_direct_result)
         async->direct_result = 0;
         async->pending = 1;
     }
+    else if (req->mark_pending)
+    {
+        async->pending = 1;
+    }
 
-    /* if the I/O has completed successfully, the client would have already
-     * set the IOSB. therefore, we can skip waiting on wait_handle and do
-     * async_set_result() directly.
+    /* if the I/O has completed successfully (or unsuccessfully, and
+     * async->pending is set), the client would have already set the IOSB.
+     * therefore, we can do async_set_result() directly and let the client skip
+     * waiting on wait_handle.
      */
     async_set_result( &async->obj, status, req->information );
 
diff --git a/server/protocol.def b/server/protocol.def
index 9d90544fa41..66c6c97b1e0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2168,6 +2168,7 @@ enum message_type
     obj_handle_t   handle;        /* wait handle */
     apc_param_t    information;   /* IO_STATUS_BLOCK Information */
     unsigned int   status;        /* completion status */
+    int            mark_pending;  /* set async to pending before completion? */
 @REPLY
     obj_handle_t   handle;        /* wait handle, or NULL if closed */
 @END
-- 
2.34.1




More information about the wine-devel mailing list