[PATCH v3 3/3] ws2_32/tests: Add a test for message ordering

Dongwan Kim kdw6485 at gmail.com
Sun Dec 12 20:08:35 CST 2021


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

diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 02713a7c625..d3db5250773 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -162,16 +162,16 @@ static GUID       WSARecvMsg_GUID = WSAID_WSARECVMSG;
 static SOCKET setup_server_socket(struct sockaddr_in *addr, int *len);
 static SOCKET setup_connector_socket(const struct sockaddr_in *addr, int len, BOOL nonblock);
 
-static void tcp_socketpair_flags(SOCKET *src, SOCKET *dst, DWORD flags)
+static void tcp_socketpair_flags2(SOCKET *src, SOCKET *dst, DWORD srcflags, DWORD dstflags)
 {
     SOCKET server = INVALID_SOCKET;
     struct sockaddr_in addr;
     int len, ret;
 
-    *src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, flags);
+    *src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, srcflags);
     ok(*src != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
 
-    server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, flags);
+    server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, dstflags);
     ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
 
     memset(&addr, 0, sizeof(addr));
@@ -196,6 +196,10 @@ static void tcp_socketpair_flags(SOCKET *src, SOCKET *dst, DWORD flags)
 
     closesocket(server);
 }
+static void tcp_socketpair_flags(SOCKET *src, SOCKET *dst, DWORD flags)
+{
+  tcp_socketpair_flags2(src,dst,flags,flags);
+}
 
 static void tcp_socketpair(SOCKET *src, SOCKET *dst)
 {
@@ -11219,6 +11223,154 @@ static DWORD CALLBACK nonblocking_async_recv_thread(void *arg)
     return 0;
 }
 
+#define BUFFERSIZE 4096
+typedef struct
+{
+  OVERLAPPED overlapped;
+  CHAR       buffer[BUFFERSIZE];
+  WSABUF     wsaBuf;
+} PER_IO_DATA, * LPPER_IO_DATA;
+
+struct SocketInfo
+{
+  SOCKET fd;
+  PER_IO_DATA perio[16];
+};
+
+static HANDLE g_hIocp;
+static unsigned char book[BUFFERSIZE<<10];
+
+static DWORD CALLBACK async_send_file_client_thread(void* arg){
+  int randlen[] = { 1476, 1886, 3887,
+    1105,
+    2460,
+    3689,
+    2942,
+    3358,
+    2221,
+    3714,
+    1739,
+    2955,
+    1769,
+    1912,
+    1401,
+    1753 };
+
+  char sendbuf[BUFFERSIZE];
+  char recvbuf[BUFFERSIZE];
+  int iResult;
+  SOCKET client = *(SOCKET*)arg;
+  int offset=0;
+  int len=0;
+
+
+  for (int i = 0; ; i =  (i+1)%16 )
+  {
+    len = offset + randlen[i] < sizeof(book) ?  randlen[i] : sizeof(book)-offset ;
+    memcpy(sendbuf, book+offset , len);
+    offset += len;
+    iResult = send(client, sendbuf, len, 0);
+    if(i==15)
+      recv(client, recvbuf, BUFFERSIZE, 0);
+    if(offset  >= sizeof(book))
+      break;
+  }
+  shutdown(client, SD_SEND);
+
+  do {
+    iResult = recv(client, recvbuf, 4096, 0);
+  } while (iResult > 0);
+
+  closesocket(client);
+
+
+  return 0;
+}
+static DWORD CALLBACK async_recv_file_iocp_thread(void* arg){
+  DWORD readn;
+  DWORD coKey;
+  DWORD flags = 0;
+  LPPER_IO_DATA perIoData;
+  struct SocketInfo* sInfo;
+  DWORD sent;
+  DWORD cnt=0;
+  DWORD offset=0;
+  unsigned char total[38267];
+
+
+  PER_IO_DATA sdata;
+  memcpy(sdata.buffer, "ok", 3);
+  sdata.wsaBuf.buf = sdata.buffer;
+  sdata.wsaBuf.len = 3;
+  while (1)
+  {
+    GetQueuedCompletionStatus(g_hIocp, &readn, (PULONG_PTR)&coKey , (LPOVERLAPPED*)&perIoData, INFINITE);
+
+    sInfo = (struct SocketInfo*)coKey;
+    if (readn == 0)
+    {
+      closesocket(sInfo->fd);
+      return 0;
+    }
+    memcpy(total+ cnt, perIoData->buffer, readn);
+    cnt+= readn;
+    if (cnt == 38267)
+    {
+      cnt = 0;
+      ok(memcmp(book+offset, total, 38267) == 0 , "message misordered...\n");
+      offset+= 38267;
+      WSASend(sInfo->fd , &(sdata.wsaBuf), 1, &sent, 0, 0, NULL);
+      for (int i = 0; i < 16; i++) {
+        readn = BUFFERSIZE;
+        WSARecv(sInfo->fd, &sInfo->perio[i].wsaBuf, 1, &readn, &flags, (LPOVERLAPPED)&sInfo->perio[i], NULL);
+      }
+    }
+
+  }
+
+  return 0;
+}
+
+
+static void test_message_ordering(void)
+{
+  SOCKET client, server;
+  HANDLE hIOCP;
+  DWORD readn;
+  struct SocketInfo sInfo;
+  DWORD flags=0;
+
+  /*initialization*/
+  tcp_socketpair_flags2(&client, &server, 0, WSA_FLAG_OVERLAPPED);
+
+  set_blocking(client, TRUE);
+  set_blocking(server, FALSE);
+  for(int i=0; i< sizeof(book); i++)
+    book[i] = rand()%256;
+
+  CreateThread(0,0, async_send_file_client_thread, &client,0, 0);
+  hIOCP = CreateThread(0,0, async_recv_file_iocp_thread, 0,0,0);
+
+  g_hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+
+  sInfo.fd = server;
+  for (int i = 0; i < 16; i++) {
+    sInfo.perio[i].wsaBuf.buf = sInfo.perio[i].buffer;
+    sInfo.perio[i].wsaBuf.len = BUFFERSIZE;
+  }
+
+  g_hIocp = CreateIoCompletionPort((HANDLE)server, g_hIocp, (unsigned long)&sInfo, 0);
+  ok(g_hIocp != NULL, "Failed to create Iocompletion");
+
+
+  for (int i = 0; i < 16; i++) {
+    readn = BUFFERSIZE;
+    WSARecv(sInfo.fd, &sInfo.perio[i].wsaBuf, 1, &readn, &flags, (LPOVERLAPPED)&sInfo.perio[i], NULL) ;
+  }
+
+
+  WaitForSingleObject(hIOCP, INFINITE);
+}
 static void test_nonblocking_async_recv(void)
 {
     struct nonblocking_async_recv_params params;
@@ -11934,6 +12086,8 @@ START_TEST( sock )
     test_shutdown();
     test_DisconnectEx();
 
+    test_message_ordering();
+
     test_completion_port();
     test_connect_completion_port();
     test_shutdown_completion_port();
-- 
2.30.2




More information about the wine-devel mailing list