From: Paul Gofman pgofman@codeweavers.com
--- dlls/ws2_32/socket.c | 2 +- dlls/ws2_32/tests/sock.c | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 5eb926a408b..930a4000b4e 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -765,7 +765,7 @@ SOCKET WINAPI accept( SOCKET s, struct sockaddr *addr, int *len ) NULL, 0, &accept_handle, sizeof(accept_handle) ); if (status == STATUS_PENDING) { - if (WaitForSingleObject( sync_event, INFINITE ) == WAIT_FAILED) + if (wait_event_alertable( sync_event ) == WAIT_FAILED) return SOCKET_ERROR; status = io.u.Status; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index cddc4c125ff..b0ef7647654 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4648,10 +4648,37 @@ static SOCKET setup_connector_socket(const struct sockaddr_in *addr, int len, BO return connector; }
+struct connect_apc_func_param +{ + HANDLE event; + struct sockaddr_in addr; + SOCKET connector; + unsigned int apc_count; +}; + +static DWORD WINAPI test_accept_connect_thread(void *param) +{ + struct connect_apc_func_param *p = (struct connect_apc_func_param *)param; + + WaitForSingleObject(p->event, INFINITE); + p->connector = setup_connector_socket(&p->addr, sizeof(p->addr), FALSE); + ok(p->connector != INVALID_SOCKET, "failed connecting from APC func.\n"); + return 0; +} + +static void WINAPI connect_apc_func(ULONG_PTR param) +{ + struct connect_apc_func_param *p = (struct connect_apc_func_param *)param; + + ++p->apc_count; + SetEvent(p->event); +} + static void test_accept(void) { int ret; SOCKET server_socket, accepted = INVALID_SOCKET, connector; + struct connect_apc_func_param apc_param; struct sockaddr_in address; SOCKADDR_STORAGE ss, ss_empty; int socklen; @@ -4666,6 +4693,23 @@ static void test_accept(void) socklen = sizeof(address); server_socket = setup_server_socket(&address, &socklen);
+ memset(&apc_param, 0, sizeof(apc_param)); + apc_param.event = CreateEventW(NULL, FALSE, FALSE, NULL); + apc_param.addr = address; + /* Connecting directly from APC function randomly crashes on Windows for some reason, + * so do it from a thread and only signal it from the APC when we are in accept() call. */ + thread_handle = CreateThread(NULL, 0, test_accept_connect_thread, &apc_param, 0, NULL); + ret = QueueUserAPC(connect_apc_func, GetCurrentThread(), (ULONG_PTR)&apc_param); + ok(ret, "QueueUserAPC returned %d\n", ret); + accepted = accept(server_socket, NULL, NULL); + ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError()); + ok(apc_param.apc_count == 1, "APC was called %u times\n", apc_param.apc_count); + closesocket(accepted); + closesocket(apc_param.connector); + WaitForSingleObject(thread_handle, INFINITE); + CloseHandle(thread_handle); + CloseHandle(apc_param.event); + connector = setup_connector_socket(&address, socklen, FALSE); if (connector == INVALID_SOCKET) goto done;
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ws2_32/socket.c | 2 +- dlls/ws2_32/tests/sock.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 930a4000b4e..267830cc88c 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1240,7 +1240,7 @@ int WINAPI connect( SOCKET s, const struct sockaddr *addr, int len ) free( params ); if (status == STATUS_PENDING) { - if (WaitForSingleObject( sync_event, INFINITE ) == WAIT_FAILED) return -1; + if (wait_event_alertable( sync_event ) == WAIT_FAILED) return -1; status = io.u.Status; } if (status) diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index b0ef7647654..70618408e90 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -8448,6 +8448,28 @@ static void test_connect(void) WSACloseEvent(overlapped.hEvent); closesocket(connector);
+ if (0) + { + /* Wait in connect() is alertable. This may take a very long time before connection fails, + * so disable the test. Testing with localhost is unreliable as that may avoid waiting in + * accept(). */ + connector = socket(AF_INET, SOCK_STREAM, 0); + ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError()); + address.sin_addr.s_addr = inet_addr("8.8.8.8"); + address.sin_port = htons(255); + + apc_count = 0; + SleepEx(0, TRUE); + ok(apc_count == 0, "got apc_count %d.\n", apc_count); + bret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count); + ok(bret, "QueueUserAPC returned %d\n", bret); + iret = connect(connector, (struct sockaddr *)&address, sizeof(address)); + ok(apc_count == 1, "got apc_count %d.\n", apc_count); + ok(iret == -1 && (WSAGetLastError() == WSAECONNREFUSED || WSAGetLastError() == WSAETIMEDOUT), + "unexpected iret %d, error %d.\n", iret, WSAGetLastError()); + closesocket(connector); + } + /* Test connect after previous connect attempt failure. */ connector = socket(AF_INET, SOCK_STREAM, 0); ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ws2_32/socket.c | 2 +- dlls/ws2_32/tests/sock.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 267830cc88c..710ec8cbb26 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2994,7 +2994,7 @@ int WINAPI WSAPoll( WSAPOLLFD *fds, ULONG count, int timeout ) params, params_size, params, params_size ); if (status == STATUS_PENDING) { - if (WaitForSingleObject( sync_event, INFINITE ) == WAIT_FAILED) + if (wait_event_alertable( sync_event ) == WAIT_FAILED) { free( params ); return -1; diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 70618408e90..ff2364b9d1d 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -8127,7 +8127,11 @@ static void test_WSAPoll(void) fds[0].fd = client; fds[0].events = POLLRDNORM | POLLRDBAND; fds[0].revents = 0xdead; + apc_count = 0; + ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count); + ok(ret, "QueueUserAPC returned %d\n", ret); ret = pWSAPoll(fds, 1, 2000); + ok(apc_count == 1, "APC was called %u times\n", apc_count); ok(ret == 1, "got %d\n", ret); ok(fds[0].revents == POLLNVAL, "got events %#x\n", fds[0].revents); ret = WaitForSingleObject(thread_handle, 1000);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index ff2364b9d1d..05001f39012 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -12662,6 +12662,19 @@ static void test_WSAGetOverlappedResult(void) } }
+ overlapped.Internal = STATUS_PENDING; + overlapped.hEvent = CreateEventW(NULL, TRUE, TRUE, NULL); + + apc_count = 0; + ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count); + ok(ret, "QueueUserAPC returned %d\n", ret); + ret = WSAGetOverlappedResult(s, &overlapped, &size, TRUE, &flags); + ok(ret && GetLastError() == ERROR_IO_PENDING, "Got ret %d, err %lu.\n", ret, GetLastError()); + ok(!apc_count, "got apc_count %d.\n", apc_count); + SleepEx(0, TRUE); + ok(apc_count == 1, "got apc_count %d.\n", apc_count); + + CloseHandle(overlapped.hEvent); closesocket(s); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=133196
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w7u_adm (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w7u_el (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w8 (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w8adm (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w864 (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w1064v1507 (32 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w7pro64 (64 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w864 (64 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w1064v1507 (64 bit report) ===
ws2_32: sock.c:12672: Test failed: Got ret 1, err 0.
=== w1064_2qxl (64 bit report) ===
ws2_32: sock.c:12840: Test failed: wait timed out