From: Paul Gofman pgofman@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ws2_32/socket.c | 10 +++++++++- dlls/ws2_32/tests/sock.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 964724b36e7..9be7190062f 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -551,6 +551,14 @@ static HANDLE get_sync_event(void) return data->sync_event; }
+static DWORD wait_event_alertable( HANDLE event ) +{ + DWORD ret; + + while ((ret = WaitForSingleObjectEx( event, INFINITE, TRUE )) == WAIT_IO_COMPLETION) + ; + return ret; +}
BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) { @@ -2769,7 +2777,7 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr, IOCTL_AFD_POLL, 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( read_input ); free( params ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 22e414e02ec..80d458b650d 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -202,6 +202,11 @@ static void tcp_socketpair(SOCKET *src, SOCKET *dst) tcp_socketpair_flags(src, dst, WSA_FLAG_OVERLAPPED); }
+static void WINAPI apc_func(ULONG_PTR apc_count) +{ + ++*(unsigned int *)apc_count; +} + /* Set the linger timeout to zero and close the socket. This will trigger an * RST on the connection on Windows as well as on Unix systems. */ static void close_with_rst(SOCKET s) @@ -3613,6 +3618,7 @@ static void test_select(void) select_thread_params thread_params; HANDLE thread_handle; DWORD ticks, id, old_protect; + unsigned int apc_count; unsigned int maxfd, i; char *page_pair;
@@ -3716,14 +3722,24 @@ static void test_select(void)
FD_ZERO(&readfds); FD_SET(fdRead, &readfds); + apc_count = 0; + ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count); + ok(ret, "QueueUserAPC returned %d\n", ret); ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout); ok(!ret, "select returned %d\n", ret); + ok(apc_count == 1, "got apc_count %d.\n", apc_count);
FD_ZERO(&writefds); FD_SET(fdWrite, &writefds); + apc_count = 0; + ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count); + ok(ret, "QueueUserAPC returned %d\n", ret); ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout); ok(ret == 1, "select returned %d\n", ret); ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n"); + ok(!apc_count, "APC was called\n"); + SleepEx(0, TRUE); + ok(apc_count == 1, "got apc_count %d.\n", apc_count);
/* select the same socket twice */ writefds.fd_count = 2;