[PATCH v2 1/3] winhttp: Don't allow websocket send if another non-control send is pending.

Hans Leidekker hans at codeweavers.com
Mon Feb 28 05:37:49 CST 2022


From: Paul Gofman <pgofman at codeweavers.com>

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 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
-- 
2.30.2




More information about the wine-devel mailing list