(WS_select): Ignore poll EINTR result code.

Dmitriy Anisimkov anisimkov at ada-ru.org
Sun Feb 1 02:16:32 CST 2009


---
 dlls/ws2_32/socket.c |   39 ++++++++++++++++++++++++++++++++++-----
 1 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index c3ee046..a50b198 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -389,7 +389,7 @@ static const int ws_eai_map[][2] =
     MAP_OPTION( EAI_FAIL ),
     MAP_OPTION( EAI_FAMILY ),
     MAP_OPTION( EAI_MEMORY ),
-/* Note: EAI_NODATA is deprecated, but still 
+/* Note: EAI_NODATA is deprecated, but still
  * used by Windows and Linux... We map the newer
  * EAI_NONAME to EAI_NODATA for now until Windows
  * changes too.
@@ -2788,8 +2788,22 @@ int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
                      const struct WS_timeval* ws_timeout)
 {
     struct pollfd *pollfds;
+    struct timeval tv1, tv2, wst;
     int count, ret, timeout = -1;
 
+    struct timeval sub_tv (struct timeval tv1, struct timeval tv2)
+    {
+        struct timeval tv;
+        tv.tv_sec = tv1.tv_sec - tv2.tv_sec;
+        tv.tv_usec = tv1.tv_usec - tv2.tv_usec;
+        if (tv.tv_usec < 0)
+        {
+            tv.tv_usec += 1000000;
+            tv.tv_sec -= 1;
+        }
+        return tv;
+    };
+
     TRACE("read %p, write %p, excp %p timeout %p\n",
           ws_readfds, ws_writefds, ws_exceptfds, ws_timeout);
 
@@ -2799,9 +2813,24 @@ int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
         return SOCKET_ERROR;
     }
 
-    if (ws_timeout) timeout = (ws_timeout->tv_sec * 1000) + (ws_timeout->tv_usec + 999) / 1000;
+    if (ws_timeout)
+    {
+        timeout = (ws_timeout->tv_sec * 1000) + (ws_timeout->tv_usec + 999) / 1000;
+        gettimeofday (&tv1, 0);
+    }
 
-    ret = poll( pollfds, count, timeout );
+    while ((ret = poll( pollfds, count, timeout )) < 0)
+    {
+        if (errno == EINTR && ws_timeout)
+        {
+            gettimeofday (&tv2, 0);
+            wst.tv_sec  = ws_timeout->tv_sec;
+            wst.tv_usec = ws_timeout->tv_usec;
+            tv2 = sub_tv (wst, sub_tv (tv2, tv1));
+            if (tv2.tv_sec < 0 || (tv2.tv_sec == 0 && tv2.tv_usec == 0)) break;
+            timeout = (tv2.tv_sec * 1000) + (tv2.tv_usec + 999) / 1000;
+        } else break;
+    };
     release_poll_fds( ws_readfds, ws_writefds, ws_exceptfds, pollfds );
 
     if (ret == -1) SetLastError(wsaErrno());
@@ -5172,7 +5201,7 @@ INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len,
 /***********************************************************************
  *              WSAAddressToStringW                      (WS2_32.28)
  *
- * Convert a sockaddr address into a readable address string. 
+ * Convert a sockaddr address into a readable address string.
  *
  * PARAMS
  *  sockaddr [I]    Pointer to a sockaddr structure.
@@ -5254,7 +5283,7 @@ INT WINAPI WSAGetServiceClassInfoA( LPGUID provider, LPGUID service, LPDWORD len
     FIXME( "(%s %s %p %p) Stub!\n", debugstr_guid(provider), debugstr_guid(service),
            len, info );
     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
-    return SOCKET_ERROR; 
+    return SOCKET_ERROR;
 }
 
 /***********************************************************************
-- 
1.5.6


--------------090005010901030402010108--



More information about the wine-devel mailing list