From 4f8fe3b1846943dbadb9725368c481b4a2ba5b96 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Wed, 8 Jun 2022 11:57:54 -0500 Subject: [PATCH] winhttp: Use completion port for async send. Signed-off-by: Paul Gofman --- dlls/winhttp/net.c | 23 +++++++++++++++++++++-- dlls/winhttp/winhttp_private.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index a17582c90a6..40c9f3c8534 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -53,9 +53,20 @@ static int sock_send(int fd, const void *msg, size_t len, WSAOVERLAPPED *ovr) BOOL netconn_wait_overlapped_result( struct netconn *conn, WSAOVERLAPPED *ovr, DWORD *len ) { - DWORD retflags; + OVERLAPPED *completion_ovr; + ULONG_PTR key; - return WSAGetOverlappedResult( conn->socket, ovr, len, TRUE, &retflags ); + if (!GetQueuedCompletionStatus( conn->port, len, &key, &completion_ovr, INFINITE )) + { + WARN( "GetQueuedCompletionStatus failed, err %lu.\n", GetLastError() ); + return FALSE; + } + if ((key != conn->socket && conn->socket != -1) || completion_ovr != (OVERLAPPED *)ovr) + { + ERR( "Unexpected completion key %Ix, overlapped %p.\n", key, completion_ovr ); + return FALSE; + } + return TRUE; } static int sock_recv(int fd, void *msg, size_t len, int flags) @@ -279,6 +290,8 @@ void netconn_close( struct netconn *conn ) if (conn->socket != -1) closesocket( conn->socket ); release_host( conn->host ); + if (conn->port) + CloseHandle( conn->port ); free(conn); } @@ -452,6 +465,12 @@ DWORD netconn_send( struct netconn *conn, const void *msg, size_t len, int *sent { DWORD err; + if (ovr && !conn->port) + { + if (!(conn->port = CreateIoCompletionPort( (HANDLE)(SOCKET)conn->socket, NULL, (ULONG_PTR)conn->socket, 0 ))) + ERR( "Failed to create port.\n" ); + } + if (conn->secure) { const BYTE *ptr = msg; diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 6c381af627f..79941dee31a 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -117,6 +117,7 @@ struct netconn char *peek_msg; char *peek_msg_mem; size_t peek_len; + HANDLE port; }; struct header