RFC linc2: EINTR handling patch



Hello,

the attached patch introduces EINTR robustnes for some IO function calls: connect, accept, writev, readv.

Calling writev or readv might be interrupted (errno==EINTR) for some reason related to kernel activity, most likely reading/writing large blocks of data;
Solution: macro LINC_TEMP_FAILURE_RETRY(opcall) loops as long as EINTR errors occure. (had been done for 'close' operation so far, only)


May I commit?

Regards, Frank






Index: linc2/src/linc-connection.c
===================================================================
RCS file: /cvs/gnome/ORBit2/linc2/src/linc-connection.c,v
retrieving revision 1.107
diff -u -r1.107 linc-connection.c
--- linc2/src/linc-connection.c	6 Feb 2004 11:32:01 -0000	1.107
+++ linc2/src/linc-connection.c	16 May 2004 23:54:19 -0000
@@ -534,7 +534,7 @@
 	if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
 		goto out;
 
-	rv = connect (fd, saddr, saddr_len);
+	rv = LINC_TEMP_FAILURE_RETRY (connect (fd, saddr, saddr_len));
 	if (rv && errno != EINPROGRESS)
 		goto out;
 
@@ -727,7 +727,9 @@
 			n = SSL_read (cnx->priv->ssl, buf, len);
 		else
 #endif
-			n = read (cnx->priv->fd, buf, len);
+			n = LINC_TEMP_FAILURE_RETRY (read (cnx->priv->fd, 
+							 buf, 
+							 len));
 
 		g_assert (n <= len);
 
@@ -851,8 +853,9 @@
 				       qw->vecs->iov_len);
 		else
 #endif
-			n = writev (cnx->priv->fd, qw->vecs,
-				    MIN (qw->nvecs, LINK_IOV_MAX));
+			n = LINC_TEMP_FAILURE_RETRY (writev (cnx->priv->fd,
+							     qw->vecs,
+							     MIN (qw->nvecs, LINK_IOV_MAX)));
 
 		d_printf ("wrote %d bytes\n", n);
 
Index: linc2/src/linc-private.h
===================================================================
RCS file: /cvs/gnome/ORBit2/linc2/src/linc-private.h,v
retrieving revision 1.30
diff -u -r1.30 linc-private.h
--- linc2/src/linc-private.h	2 Feb 2004 16:29:05 -0000	1.30
+++ linc2/src/linc-private.h	16 May 2004 23:54:19 -0000
@@ -112,6 +112,14 @@
 #define LINK_ERR_CONDS (G_IO_ERR|G_IO_HUP|G_IO_NVAL)
 #define LINK_IN_CONDS  (G_IO_PRI|G_IO_IN)
 
+/* taken from  glibc  */ 
+# define LINC_TEMP_FAILURE_RETRY(expression) \
+  (__extension__                                                              \
+    ({ long int __result;                                                     \
+       do __result = (long int) (expression);                                 \
+       while (__result == -1L && errno == EINTR);                             \
+       __result; }))
+
 #define LINK_CLOSE(fd)  while (close (fd) < 0 && errno == EINTR)
 
 const char      *link_get_local_hostname    (void);
Index: linc2/src/linc-server.c
===================================================================
RCS file: /cvs/gnome/ORBit2/linc2/src/linc-server.c,v
retrieving revision 1.62
diff -u -r1.62 linc-server.c
--- linc2/src/linc-server.c	2 Feb 2004 16:29:05 -0000	1.62
+++ linc2/src/linc-server.c	16 May 2004 23:54:19 -0000
@@ -140,7 +140,9 @@
 	addrlen = server->proto->addr_len;
 	saddr = g_alloca (addrlen);
 
-	fd = accept (server->priv->fd, saddr, &addrlen);
+	fd = LINC_TEMP_FAILURE_RETRY(accept (server->priv->fd, 
+					     saddr, 
+					     &addrlen));
 	if (fd < 0) {
 		d_printf ("accept on %d failed %d", server->priv->fd, errno);
 		return FALSE; /* error */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]