[Bug 14195] New: EINTR in WS_select

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jun 29 23:43:42 CDT 2008


http://bugs.winehq.org/show_bug.cgi?id=14195

           Summary: EINTR in WS_select
           Product: Wine
           Version: CVS/GIT
          Platform: Other
        OS/Version: other
            Status: UNCONFIRMED
          Severity: major
          Priority: P2
         Component: winsock
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: anisimkov at ada-ru.org


I have an Win32 application written in Borland Delphi using Eureka tool
(http://www.eurekalog.com/)
working in Wine but with one error.
If exception occured in main thread,
WinAPI 'select' call in secondary thread interrupted with WSAINTR error code.
The short Delphi example is in the attached sample.tar.bz2.

WSAINTR result in Win32 select mean

"A blocking Windows Socket 1.1 call was canceled through
WSACancelBlockingCall."
(http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx)

But

"The WSACancelBlockingCall function has been removed in compliance with the
Windows Sockets 2 specification, revision 2.2.0.
The function is not exported directly by WS2_32.DLL and Windows Sockets 2
applications should not use this function.
Windows Sockets 1.1 applications that call this function are still supported
through the WINSOCK.DLL and WSOCK32.DLL."
(http://msdn.microsoft.com/en-us/library/ms741547(VS.85).aspx)

Wine translates EINTR error code into WSAINTR error code.
But in Linux EINTR have a different meaning

"EINTR  A signal occurred before any requested event."
(man poll)

I propose the following patch to ignore the EINTR error code in Wine
'WS_select' based on Linux poll call:

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index fa908b4..a98717e 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2591,7 +2591,10 @@ int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,

     if (ws_timeout) timeout = (ws_timeout->tv_sec * 1000) +
(ws_timeout->tv_usec + 999) / 1000;

-    ret = poll( pollfds, count, timeout );
+    while ((ret = poll( pollfds, count, timeout )) < 0)
+    {
+        if (errno != EINTR) break;
+    };
     release_poll_fds( ws_readfds, ws_writefds, ws_exceptfds, pollfds );

     if (ret == -1) SetLastError(wsaErrno());

The wine already have a similar EINTR ignore

git-diff 84232099^ 84232099 -- dlls/winsock/socket.c
index cfbf49f..0f1ba34 100644
--- a/dlls/winsock/socket.c
+++ b/dlls/winsock/socket.c
@@ -589,7 +589,13 @@ static inline int do_block( int fd, int events )

   pfd.fd = fd;
   pfd.events = events;
-  poll(&pfd, 1, -1);
+
+  while (poll(&pfd, 1, -1) < 0)
+  {
+      if (errno != EINTR)
+          return -1;
+  }
+
   return pfd.revents;
 }


Thank you for attension and for great software.
Best regards.

Dmitriy Anisimkov.


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list