[PATCH v4 3/3] ws2_32/tests: Add a test for message ordering
Dongwan Kim
kdw6485 at gmail.com
Wed Dec 15 19:27:34 CST 2021
Signed-off-by: Dongwan Kim <kdw6485 at gmail.com>
---
dlls/ws2_32/tests/sock.c | 162 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 159 insertions(+), 3 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 02713a7c625..47ce08088a0 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,155 @@ 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);
+ CloseHandle(g_hIocp);
+}
static void test_nonblocking_async_recv(void)
{
struct nonblocking_async_recv_params params;
@@ -11882,6 +12035,8 @@ START_TEST( sock )
Init();
+ test_message_ordering();
+
test_set_getsockopt();
test_so_reuseaddr();
test_ip_pktinfo();
@@ -11934,6 +12089,7 @@ START_TEST( sock )
test_shutdown();
test_DisconnectEx();
+
test_completion_port();
test_connect_completion_port();
test_shutdown_completion_port();
--
2.30.2
More information about the wine-devel
mailing list