From: Paul Gofman Subject: [PATCH 5/5] winhttp: Allow synchronous nonblocking send in socket_send_pong(). Message-Id: <20220126230309.1530051-5-pgofman@codeweavers.com> Date: Thu, 27 Jan 2022 02:03:09 +0300 In-Reply-To: <20220126230309.1530051-1-pgofman@codeweavers.com> References: <20220126230309.1530051-1-pgofman@codeweavers.com> Signed-off-by: Paul Gofman --- dlls/winhttp/request.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 62f53995258..ff2c18c469b 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -3505,7 +3505,10 @@ static void CALLBACK task_socket_send_pong( TP_CALLBACK_INSTANCE *instance, void struct socket_send *s = ctx; TRACE("running %p\n", work); - send_frame( s->socket, SOCKET_OPCODE_PONG, 0, NULL, 0, TRUE, NULL ); + + if (s->complete_async) complete_send_frame( s->socket, &s->ovr, NULL ); + else send_frame( s->socket, SOCKET_OPCODE_PONG, 0, NULL, 0, TRUE, NULL ); + send_io_complete( &s->socket->hdr ); release_object( &s->socket->hdr ); @@ -3516,18 +3519,38 @@ static DWORD socket_send_pong( struct socket *socket ) { if (socket->request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) { + BOOL async_send, complete_async = FALSE; struct socket_send *s; - DWORD ret; + DWORD ret = 0; if (!(s = malloc( sizeof(*s) ))) return ERROR_OUTOFMEMORY; - s->socket = socket; - addref_object( &socket->hdr ); - InterlockedIncrement( &socket->hdr.pending_sends ); - if ((ret = queue_task( &socket->send_q, task_socket_send_pong, s ))) + async_send = InterlockedIncrement( &socket->hdr.pending_sends ) > 1; + if (!async_send) + { + memset( &s->ovr, 0, sizeof(s->ovr) ); + if ((ret = send_frame( socket, SOCKET_OPCODE_PONG, 0, NULL, 0, TRUE, &s->ovr )) == WSA_IO_PENDING) + { + async_send = TRUE; + complete_async = TRUE; + } + } + + if (async_send) + { + s->complete_async = complete_async; + s->socket = socket; + addref_object( &socket->hdr ); + if ((ret = queue_task( &socket->send_q, task_socket_send_pong, s ))) + { + InterlockedDecrement( &socket->hdr.pending_sends ); + release_object( &socket->hdr ); + free( s ); + } + } + else { InterlockedDecrement( &socket->hdr.pending_sends ); - release_object( &socket->hdr ); free( s ); } return ret; -- 2.34.1