Module: wine Branch: master Commit: 11c835d4718aff84c8250084128f29a7fb7e7ef8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=11c835d4718aff84c82500841...
Author: Paul Gofman pgofman@codeweavers.com Date: Mon Feb 28 12:37:49 2022 +0100
winhttp: Don't allow websocket send if another non-control send is pending.
Signed-off-by: Paul Gofman pgofman@codeweavers.com Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winhttp/request.c | 16 +++++++++++++++- dlls/winhttp/winhttp_private.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index d0732952e11..de011060236 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -3349,6 +3349,7 @@ static void CALLBACK task_socket_send( TP_CALLBACK_INSTANCE *instance, void *ctx else ret = socket_send( s->socket, s->type, s->buf, s->len, NULL );
send_io_complete( &s->socket->hdr ); + InterlockedExchange( &s->socket->pending_noncontrol_send, 0 ); socket_send_complete( s->socket, ret, s->type, s->len );
release_object( &s->socket->hdr ); @@ -3386,8 +3387,16 @@ DWORD WINAPI WinHttpWebSocketSend( HINTERNET hsocket, WINHTTP_WEB_SOCKET_BUFFER_ BOOL async_send, complete_async = FALSE; struct socket_send *s;
+ if (InterlockedCompareExchange( &socket->pending_noncontrol_send, 1, 0 )) + { + WARN( "Previous send is still queued.\n" ); + release_object( &socket->hdr ); + return ERROR_INVALID_OPERATION; + } + if (!(s = malloc( sizeof(*s) ))) { + InterlockedExchange( &socket->pending_noncontrol_send, 0 ); release_object( &socket->hdr ); return ERROR_OUTOFMEMORY; } @@ -3417,11 +3426,16 @@ DWORD WINAPI WinHttpWebSocketSend( HINTERNET hsocket, WINHTTP_WEB_SOCKET_BUFFER_ if ((ret = queue_task( &socket->send_q, task_socket_send, s ))) { InterlockedDecrement( &socket->hdr.pending_sends ); + InterlockedExchange( &socket->pending_noncontrol_send, 0 ); release_object( &socket->hdr ); free( s ); } } - else InterlockedDecrement( &socket->hdr.pending_sends ); + else + { + InterlockedDecrement( &socket->hdr.pending_sends ); + InterlockedExchange( &socket->pending_noncontrol_send, 0 ); + } ReleaseSRWLockExclusive( &socket->send_lock ); if (!async_send) { diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 732f0afaa88..cf6655f561f 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -260,6 +260,7 @@ struct socket unsigned int bytes_in_send_frame_buffer; unsigned int client_buffer_offset; SRWLOCK send_lock; + volatile LONG pending_noncontrol_send; };
struct send_request