[PATCH] Fixed brain fart: Quickly retry recvmsg or sendmsg if errno is EINTR or EAGAIN

mtewoodbury at gmail.com mtewoodbury at gmail.com
Fri Feb 28 01:55:55 CST 2014


From: Max TenEyck Woodbury <max+git at mtew.isa-geek.net>

EAGAIN happens when some kernel resource is _temporarily_ unavailable.
The return to application level may have allowed a thread switch or some
other action that freed the resource, so ONE attempted retry could find
the problem cleared.  If it does not clear, some higher level checks are
needed.

EINTR is similar, but could happen multiple times.  It is a matter of
chance.  One retry increases the odds of success a lot.  Multiple
retries, less so.  A loop here could cause a problem, since it would
have to be limited in some way.  So try again once...

I observed an increase in network reliability with this patch.  The
auto-login feature of Guild Wars 2 almost never fails now where it
failed with moderate frequency before.  Also, the trading post was
unusable without this patch, but now works nicely.
---
 dlls/ws2_32/socket.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 2a2c809..0e006e7 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1921,7 +1921,10 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
     hdr.msg_flags = 0;
 #endif
 
-    if ( (n = recvmsg(fd, &hdr, wsa->flags)) == -1 )
+    n = recvmsg(fd, &hdr, wsa->flags)
+    if ( n == -1 && (errno == EINTR || errno == EAGAIN))
+        n = recvmsg(fd, &hdr, wsa->flags)
+    if ( n == -1 )
         return -1;
 
 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
@@ -2173,6 +2176,8 @@ static int WS2_send( int fd, struct ws2_async *wsa )
 #endif
 
     ret = sendmsg(fd, &hdr, wsa->flags);
+    if (ret == -1 && (errno == EINTR || errno == EAGAIN))
+        ret = sendmsg(fd, &hdr, wsa->flags);
     if (ret >= 0)
     {
         n = ret;
-- 
1.8.0.rc0.18.gf84667d




More information about the wine-patches mailing list