[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