[PATCH] Add quick retrys of recvmsg and semdmsg on failures with errno of EINTR or EAGAIN.

Max Woodbury mtewoodbury at gmail.com
Sat Mar 1 03:47:27 CST 2014


 From 60fa4fcb0036c8ef42e7f237ff828108feef1a1f Mon Sep 17 00:00:00 2001
Date: Sat, 1 Mar 2014 04:10:42 -0500

EAGAIN indicates a _temporary_ lack of internal kernel resources.
Returning to application level may allow a task switch or other action
that frees the resource.  ONE retry allows a quick recovery when that
happens.  If the retry fails, some higher level strategic recovery is
needed.  Those steps are already in place and should not be changed.

EINTER is similar.  It happens as a mater of chance.  A quick retry has
a good chance of recovering.  The chances go down a lot if additional
retries are needed.  A loop at this level is NOT a good idea because a
way to break the loop has to be in place if it runs too long.

The added blank line before the 'return' is there to make it stand out.
This is a fairly common practice elsewhere in the wine code.

A separate test for this would be very difficult to construct since
many factors not under application control have to come together to
cause the problems these changes address.  On the other hand, the game
Guild Wars 2 shows considerably fewer problems with this patch in place.
In particular, automatic login failures went from moderatly frequent to
almost non-existant.  The trading post feature which was unusable
without this patch now works quite well.
---
  dlls/ws2_32/socket.c | 8 +++++++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 2a2c809..47b5ecc 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1921,7 +1921,11 @@ 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 +2177,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