Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/ws2_32/tests/sock.c | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index d4585c2b1dc..57ff496cfb8 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -11451,6 +11451,60 @@ static void test_nonblocking_async_recv(void) CloseHandle(overlapped.hEvent); }
+static void test_simultaneous_async_recv(void) +{ + SOCKET client, server; + OVERLAPPED overlappeds[2] = {{0}}; + HANDLE events[2]; + WSABUF wsabufs[2]; + DWORD flags[2] = {0}; + size_t num_io = 2, stride = 16, i; + char resbuf[32] = ""; + static const char msgstr[32] = "-- Lorem ipsum dolor sit amet -"; + int ret; + + for (i = 0; i < num_io; i++) events[i] = CreateEventW(NULL, TRUE, FALSE, NULL); + + tcp_socketpair(&client, &server); + + for (i = 0; i < num_io; i++) + { + wsabufs[i].buf = resbuf + i * stride; + wsabufs[i].len = stride; + overlappeds[i].hEvent = events[i]; + ret = WSARecv(client, &wsabufs[i], 1, NULL, &flags[i], &overlappeds[i], NULL); + ok(ret == -1, "got %d\n", ret); + ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError()); + } + + ret = send(server, msgstr, sizeof(msgstr), 0); + ok(ret == sizeof(msgstr), "got %d\n", ret); + + for (i = 0; i < num_io; i++) + { + const void *expect = msgstr + i * stride; + const void *actual = resbuf + i * stride; + DWORD size; + + ret = WaitForSingleObject(events[i], 1000); + todo_wine_if(i > 0) + ok(!ret, "wait timed out\n"); + + ret = GetOverlappedResult((HANDLE)client, &overlappeds[i], &size, FALSE); + todo_wine_if(i > 0) + ok(ret, "got error %u\n", GetLastError()); + todo_wine_if(i > 0) + ok(size == stride, "got size %u\n", size); + todo_wine_if(i > 0) + ok(!memcmp(expect, actual, stride), "expected %s, got %s\n", debugstr_an(expect, stride), debugstr_an(actual, stride)); + } + + closesocket(client); + closesocket(server); + + for (i = 0; i < num_io; i++) CloseHandle(events[i]); +} + static void test_empty_recv(void) { OVERLAPPED overlapped = {0}; @@ -12009,6 +12063,7 @@ START_TEST( sock ) test_connecting_socket(); test_WSAGetOverlappedResult(); test_nonblocking_async_recv(); + test_simultaneous_async_recv(); test_empty_recv(); test_timeout();
Otherwise, async_waiting() returns 0, leading the socket object to believe that the previous async request has not yet been acknowledged. This results in I/O hang for subsequent reads (until shutdown).
Also, async_destroy() calls async_reselect() only after removing the async request from the queue. Make async_set_result() consistent with this behaviour.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52332 Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/ws2_32/tests/sock.c | 4 ---- server/async.c | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 57ff496cfb8..85275a745de 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -11487,15 +11487,11 @@ static void test_simultaneous_async_recv(void) DWORD size;
ret = WaitForSingleObject(events[i], 1000); - todo_wine_if(i > 0) ok(!ret, "wait timed out\n");
ret = GetOverlappedResult((HANDLE)client, &overlappeds[i], &size, FALSE); - todo_wine_if(i > 0) ok(ret, "got error %u\n", GetLastError()); - todo_wine_if(i > 0) ok(size == stride, "got size %u\n", size); - todo_wine_if(i > 0) ok(!memcmp(expect, actual, stride), "expected %s, got %s\n", debugstr_an(expect, stride), debugstr_an(actual, stride)); }
diff --git a/server/async.c b/server/async.c index 1a564ff1a69..7aef28355f0 100644 --- a/server/async.c +++ b/server/async.c @@ -509,12 +509,11 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota async->completion_callback( async->completion_callback_private ); async->completion_callback = NULL;
- async_reselect( async ); - if (async->queue) { - async->fd = NULL; list_remove( &async->queue_entry ); + async_reselect( async ); + async->fd = NULL; async->queue = NULL; release_object( async ); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=104814
Your paranoid android.
=== debian11 (32 bit report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit Arabic:Morocco report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit German report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit French report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit Hebrew:Israel report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit Hindi:India report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit Japanese:Japan report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit Chinese:China report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (32 bit WoW report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16
=== debian11 (64 bit WoW report) ===
ws2_32: sock.c:11497: Test succeeded inside todo block: got size 16