Signed-off-by: Dongwan Kim kdw6485@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, ¶ms, 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();