[PATCH 2/3] ntdll: Skip needless wait for pending completion port if timeout is zero

Andrew Eikum aeikum at codeweavers.com
Tue Nov 23 11:19:48 CST 2021


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/ntdll/unix/sync.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 7fad8250e43..c392eb172b2 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -1824,7 +1824,7 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE handle, ULONG_PTR *key, ULONG_PTR *
         SERVER_START_REQ( remove_completion )
         {
             req->handle = wine_server_obj_handle( wait_handle );
-            req->alloc_wait_handle = wait_handle == handle;
+            req->alloc_wait_handle = wait_handle == handle && (!timeout || timeout->QuadPart != 0);
             if (!(status = wine_server_call( req )))
             {
                 *key            = reply->ckey;
@@ -1839,7 +1839,10 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE handle, ULONG_PTR *key, ULONG_PTR *
         }
         SERVER_END_REQ;
         if (status != STATUS_PENDING) goto exit;
-        status = NtWaitForSingleObject( wait_handle, FALSE, timeout );
+        if (wait_handle != handle)
+            status = NtWaitForSingleObject( wait_handle, FALSE, timeout );
+        else
+            status = STATUS_TIMEOUT;
         if (status != WAIT_OBJECT_0) goto exit;
     }
 
@@ -1870,7 +1873,7 @@ NTSTATUS WINAPI NtRemoveIoCompletionEx( HANDLE handle, FILE_IO_COMPLETION_INFORM
             SERVER_START_REQ( remove_completion )
             {
                 req->handle = wine_server_obj_handle( wait_handle );
-                req->alloc_wait_handle = wait_handle == handle;
+                req->alloc_wait_handle = wait_handle == handle && (!timeout || timeout->QuadPart != 0);
                 if (!(status = wine_server_call( req )))
                 {
                     info[i].CompletionKey             = reply->ckey;
@@ -1892,7 +1895,12 @@ NTSTATUS WINAPI NtRemoveIoCompletionEx( HANDLE handle, FILE_IO_COMPLETION_INFORM
             if (status == STATUS_PENDING) status = STATUS_SUCCESS;
             break;
         }
-        status = NtWaitForSingleObject( wait_handle, alertable, timeout );
+        if (wait_handle != handle)
+            status = NtWaitForSingleObject( wait_handle, alertable, timeout );
+        else if (alertable)
+            status = NtDelayExecution( TRUE, timeout ); /* query for APC */
+        else
+            status = STATUS_TIMEOUT;
         if (status != WAIT_OBJECT_0) break;
     }
     *written = i ? i : 1;
-- 
2.34.0





More information about the wine-devel mailing list