[PATCH v4 2/2] ws2_32/tests : Add a test for message ordering problem

Dongwan Kim kdw6485 at gmail.com
Tue May 18 01:41:47 CDT 2021


Signed-off-by: Dongwan Kim <kdw6485 at gmail.com>
---
 dlls/ws2_32/tests/sock.c | 124 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 33cdd5d6d15..bca3db9cbe6 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -9903,6 +9903,129 @@ static void test_empty_recv(void)
     CloseHandle(overlapped.hEvent);
 }
 
+/* io data for WSARecv */
+typedef struct
+{
+	OVERLAPPED 		overlapped;
+	CHAR 			buffer[8000];
+	WSABUF 			wsaBuf;
+}IO_DATA;
+struct async_worker_params
+{
+    SOCKET socket;
+    DWORD ret;
+};
+
+static IO_DATA g_iodata[16];
+static HANDLE g_hIocp;
+static DWORD check_ordering(char* buffer, int len , int cnt)
+{
+	int i;
+	for(i=0; i< len; i++)
+		if((unsigned char )buffer[i] != (cnt+i) % 256){
+			ok((unsigned char)buffer[i] == (cnt+i)%256, "%d , expected %d\n",(unsigned char)buffer[i], (cnt+i)%256);
+			return 0;
+		}
+	return 1;
+}
+static DWORD CALLBACK async_recv_worker(void* arg)
+{
+    struct async_worker_params *params = arg;
+	int i ;
+	DWORD readn, arranged=1, cnt=0;
+	ULONG_PTR coKey;
+	DWORD flags = 0;
+	IO_DATA* io_data;
+
+	while(1)
+	{
+		GetQueuedCompletionStatus(g_hIocp, &readn, &coKey, (LPOVERLAPPED*)&io_data, INFINITE);
+		if(readn == 0 )
+		{
+			break;
+		}
+		arranged = arranged & check_ordering(io_data->buffer,  readn, cnt);
+		cnt+= readn;
+		if(cnt == 16*4096)
+		{
+			cnt=0;
+			send(params->socket, "1", 1,0);
+			for(i=0;i < 16; i++)
+			{
+				WSARecv(params->socket, &g_iodata[i].wsaBuf, 1, &readn, &flags, (LPOVERLAPPED)&g_iodata[i], NULL);
+			}
+		}
+	}
+	params->ret = arranged;
+	return 0;
+}
+static DWORD CALLBACK async_recv_until_close(SOCKET server)
+{
+    int i;
+    DWORD flags=0;
+
+    HANDLE worker;
+
+    struct async_worker_params params;
+    params.socket = server;
+	worker = CreateThread(NULL,0,async_recv_worker, &params, 0, NULL);
+	g_hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,0 );
+
+	g_hIocp = CreateIoCompletionPort((HANDLE)server, g_hIocp, 0, 0);
+
+	for(i=0; i< 16; i++)
+	{
+		g_iodata[i].wsaBuf.buf = g_iodata[i].buffer;
+		g_iodata[i].wsaBuf.len = sizeof(g_iodata[i].buffer);
+		WSARecv(server, &g_iodata[i].wsaBuf, 1, NULL, &flags, (LPOVERLAPPED)&g_iodata[i], NULL);
+	}
+	WaitForSingleObject(worker,INFINITE);
+
+	return params.ret;
+
+}
+static DWORD CALLBACK send_large_data( void* arg )
+{
+	SOCKET *client = arg;
+	int i,j;
+	unsigned char sendbuffer[4096];
+	char recvbuffer[5];
+	for(i=0; i < sizeof(sendbuffer); i++)
+	{
+		sendbuffer[i] = i %256;
+	}
+
+	for(j=0; j< 1000 ; j++)
+	{
+		for(i=0; i < 16; i++)
+		{
+			send(*client , (char*)sendbuffer, sizeof(sendbuffer), 0 );
+
+		}
+		recv(*client, recvbuffer, sizeof(recvbuffer), 0);
+	}
+	shutdown(*client, SD_SEND);
+	return 0;
+}
+
+static void test_message_ordering(void)
+{
+
+    SOCKET client, server;
+    DWORD ret;
+    HANDLE thread;
+    /* message ordering test */
+
+    tcp_socketpair(&client, &server);
+    thread = CreateThread(NULL, 0 , send_large_data, &client,0,NULL);
+    ret = async_recv_until_close(server);
+    WaitForSingleObject(thread,INFINITE);
+    ok(ret == 1, "message ordering failed\n");
+    closesocket(client);
+    closesocket(server);
+
+}
+
 START_TEST( sock )
 {
     int i;
@@ -9966,6 +10089,7 @@ START_TEST( sock )
     test_empty_recv();
 
     /* this is an io heavy test, do it at the end so the kernel doesn't start dropping packets */
+    test_message_ordering();
     test_send();
     test_synchronous_WSAIoctl();
     test_wsaioctl();
-- 
2.30.2




More information about the wine-devel mailing list