[PATCH 1/2] ws2_32: Make wait in select() alertable.

Paul Gofman wine at gitlab.winehq.org
Tue May 24 21:00:36 CDT 2022


From: Paul Gofman <pgofman at 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 88089fa8d74..6507f2e3c5b 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 )
 {
@@ -2601,7 +2609,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 bdb683e6796..36672b22aef 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -3448,6 +3448,11 @@ static void test_listen(void)
     ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
 }
 
+static void WINAPI apc_func(ULONG_PTR apc_called)
+{
+    *(BOOL *)apc_called = TRUE;
+}
+
 #define FD_ZERO_ALL() { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); }
 #define FD_SET_ALL(s) { FD_SET(s, &readfds); FD_SET(s, &writefds); FD_SET(s, &exceptfds); }
 static void test_select(void)
@@ -3465,6 +3470,7 @@ static void test_select(void)
     DWORD ticks, id, old_protect;
     unsigned int maxfd, i;
     char *page_pair;
+    BOOL apc_called;
 
     fdRead = socket(AF_INET, SOCK_STREAM, 0);
     ok( (fdRead != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
@@ -3566,14 +3572,24 @@ static void test_select(void)
 
     FD_ZERO(&readfds);
     FD_SET(fdRead, &readfds);
+    apc_called = FALSE;
+    ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_called);
+    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_called, "APC was not called\n");
 
     FD_ZERO(&writefds);
     FD_SET(fdWrite, &writefds);
+    apc_called = FALSE;
+    ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_called);
+    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_called, "APC was called\n");
+    SleepEx(0, TRUE);
+    ok(apc_called, "APC was not called\n");
 
     /* select the same socket twice */
     writefds.fd_count = 2;
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/127



More information about the wine-devel mailing list