By default, synchronously completed socket operations will still send completions, we currently don't mind that in winhttp. The most essential part is patch 1, which will also avoid stacking those completions. Patch 2 is not strictly necessary since now we indeed shouldn't be getting unexpected completions, but it seems to me it is better not to fully rely on that and skip unexpected ones just in case.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/net.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 6eeb1cb5ac9..3a5847865bf 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -25,6 +25,7 @@ #include "ws2tcpip.h" #include "winhttp.h" #include "schannel.h" +#include "winternl.h"
#include "wine/debug.h" #include "winhttp_private.h" @@ -223,6 +224,8 @@ DWORD netconn_create( struct hostdata *host, const struct sockaddr_storage *sock free( conn ); return ret; } + if (!SetFileCompletionNotificationModes( (HANDLE)(UINT_PTR)conn->socket, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS )) + ERR( "SetFileCompletionNotificationModes failed.\n" );
switch (conn->sockaddr.ss_family) {
From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/net.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 3a5847865bf..e46f2023fae 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -56,15 +56,16 @@ BOOL netconn_wait_overlapped_result( struct netconn *conn, WSAOVERLAPPED *ovr, D OVERLAPPED *completion_ovr; ULONG_PTR key;
- if (!GetQueuedCompletionStatus( conn->port, len, &key, &completion_ovr, INFINITE )) + while (1) { - 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; + if (!GetQueuedCompletionStatus( conn->port, len, &key, &completion_ovr, INFINITE )) + { + WARN( "GetQueuedCompletionStatus failed, err %lu.\n", GetLastError() ); + return FALSE; + } + if (completion_ovr == (OVERLAPPED *)ovr && (key == conn->socket || conn->socket == -1)) + break; + ERR( "Unexpected completion key %Ix, completion ovr %p, ovr %p.\n", key, completion_ovr, ovr ); } return TRUE; }
This merge request was approved by Hans Leidekker.