ORBit stable massive allocation issue ...



Hi Guys,

	Since this issue was beautifully repeatable on the local Ultra2, I
spent a while fixing it - as suspected the bogus g_writev was at fault,
the new version is correct (and pleasant to look at).

	This should fix the outstanding HP and Sun ORBit issues, I'll do a
release after a little more Linux testing, with it evolution works
nicely on Ultra 2 and nautilus dies from an eel linking error instead of
"can't allocate whole world" type thing.

	HTH,

		Michael.

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/ORBit/ChangeLog,v
retrieving revision 1.11.4.15
diff -u -p -u -r1.11.4.15 ChangeLog
--- ChangeLog	11 Feb 2002 16:13:56 -0000	1.11.4.15
+++ ChangeLog	11 Mar 2002 12:35:54 -0000
@@ -1,3 +1,14 @@
+2002-03-11  Michael Meeks  <michael@ximian.com>
+
+	* src/IIOP/giop-msg-buffer.c
+	kill #define writev mess.
+	(giop_send_buffer_write): handle EINTR, handle EAGAIN
+	correctly, handle short writev's correctly, test
+	thorougly.
+
+	* src/ORBitutil/compat.c (g_writev): kill this
+	abomination.
+
 2002-02-11  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 
 	* src/orb/allocators.h, src/orb/allocators.c (ORBit_alloc_2,
Index: src/IIOP/giop-msg-buffer.c
===================================================================
RCS file: /cvs/gnome/ORBit/src/IIOP/giop-msg-buffer.c,v
retrieving revision 1.117.4.9
diff -u -p -u -r1.117.4.9 giop-msg-buffer.c
--- src/IIOP/giop-msg-buffer.c	2 Oct 2001 07:19:18 -0000	1.117.4.9
+++ src/IIOP/giop-msg-buffer.c	11 Mar 2002 12:35:58 -0000
@@ -34,11 +34,7 @@
 #include "IIOP.h"
 #include "IIOP-private.h"
 
-#ifdef HAVE_LIMITED_WRITEV
-#define writev g_writev
-#endif
-
-/* type defs */
+#define MAX_LIMITED_IOVECS 16
 
 #ifdef        __GNUC__
 #define       PACKED __attribute__((packed))
@@ -172,76 +168,92 @@ giop_send_buffer_new(void)
 gint
 giop_send_buffer_write(GIOPSendBuffer *send_buffer)
 {
-  gulong nvecs;
-  glong res, sum, t;
-  struct iovec *curvec;
-  int fd;
-  GIOPConnection *cnx;
-  gint retval = -1;
-
-  cnx = GIOP_MESSAGE_BUFFER(send_buffer)->connection;
-  if(!cnx->is_valid)
-    return -1;
-
-  fd = GIOP_CONNECTION_GET_FD(cnx);
-  nvecs = GIOP_MESSAGE_BUFFER(send_buffer)->iovecs->len;
-  curvec = (struct iovec *)GIOP_MESSAGE_BUFFER(send_buffer)->iovecs->data;
-
-#if defined(ORBIT_DEBUG) && 0
-  g_print("Message of length %d looks like:\n",
-	  GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size);
-  for(sum = 0, t = 2; t < nvecs; t++) {
-
-    sum += curvec[t].iov_len;
-    g_print("    [%p, %d]: %d\n", curvec[t].iov_base, curvec[t].iov_len,
-	    sum);
-  }
+	gulong nvecs;
+	glong res, length_to_write;
+	struct iovec *curvec;
+	int fd;
+	gboolean set_blocking;
+	GIOPConnection *cnx;
+	gint retval = -1;
+
+	cnx = GIOP_MESSAGE_BUFFER (send_buffer)->connection;
+	if (!cnx->is_valid)
+		return -1;
+
+	fd = GIOP_CONNECTION_GET_FD (cnx);
+	nvecs = GIOP_MESSAGE_BUFFER (send_buffer)->iovecs->len;
+	curvec = (struct iovec *) GIOP_MESSAGE_BUFFER (send_buffer)->iovecs->data;
+
+#if defined (ORBIT_DEBUG) && 0
+	{
+		gulong sum, t;
+
+		g_print ("Message of length %d looks like:\n",
+			 GIOP_MESSAGE_BUFFER (send_buffer)->message_header.message_size);
+		for (sum = 0, t = 0; t < nvecs; t++) {
+			sum += curvec[t].iov_len;
+			g_print ("    [%p, %d]: cumul. %ld   - vec idx %d\n",
+				 curvec[t].iov_base,
+				 curvec[t].iov_len, sum, t);
+		}
+	}
 #endif
-  res = writev(fd, curvec, nvecs);
+	length_to_write = sizeof (GIOPMessageHeader)+ 
+		GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size;
+	set_blocking = FALSE;
+	do {
+  
+		do {
+#ifdef HAVE_LIMITED_WRITEV
+/*			fprintf (stderr, "ltw %ld write %d vecs, first of length %d ",
+			length_to_write, nvecs, (int) curvec->iov_len);*/
+			res = writev (fd, curvec, MIN (nvecs, MAX_LIMITED_IOVECS));
+/*			fprintf (stderr, "wrote %ld bytes [%d]\n", res, (int) errno); */
+#else
+			res = writev (fd, curvec, nvecs);
+#endif
+		} while (res < 0 && errno == EINTR);
 
-  sum = (GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size + sizeof(GIOPMessageHeader));
-  if(res < sum) {
-    if(res < 0) {
-      if(errno != EAGAIN) {
-	giop_main_handle_connection_exception(cnx);
-	goto out;
-      }
-
-      res = 0;
-    }
-
-    /* wrote 7, iovecs 3, 2, 2, 4:
-       0 + 3 !> 7
-       3 + 2 !> 7
-       5 + 2 !> 7
-     */
-
-    for(t = 0; ; t += curvec->iov_len, curvec++, nvecs--) {
-      if((t + curvec->iov_len) > res)
-	break;
-    }
-    if((res - t) > 0) {
-      curvec->iov_len -= (res - t);
-      curvec->iov_base = (gpointer)((char *)curvec->iov_base + (res - t));
-    }
-
-    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
-
-    t = writev(fd, curvec, nvecs);
-
-    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
-
-    if((t < 0) || ((res + t) < sum)) {
-	giop_main_handle_connection_exception(cnx);
-	goto out;
-    }
-  }
+		if (res < 0) {
+			if (errno != EAGAIN) {
+				giop_main_handle_connection_exception (cnx);
+				goto out;
+			} else
+				res = 0;
+		}
+
+		length_to_write -= res;
+
+		/* Move along the vector array */
+		if (length_to_write > 0) {
+			gulong t;
+
+			if (!set_blocking) {
+				set_blocking = TRUE;
+				fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) & ~O_NONBLOCK);
+			}
+
+			for (t = 0; (t + curvec->iov_len) <= res; ) {
+				t += curvec->iov_len;
+				curvec++, nvecs--;
+			}
+			/* t is now the count of the bytes in completely written iovecs */
+
+			if ((res - t) > 0) {
+				curvec->iov_len -= (res - t);
+				curvec->iov_base = ((guchar *)curvec->iov_base + (res - t));
+			}
+		}
 
-  retval = 0;
+	} while (length_to_write > 0);
 
- out:
+	if (set_blocking)
+		fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK);
 
-  return retval;
+	retval = 0;
+
+ out:
+	return retval;
 }
 
 static GIOPSendBuffer *
Index: src/ORBitutil/compat.c
===================================================================
RCS file: /cvs/gnome/ORBit/src/ORBitutil/compat.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 compat.c
--- src/ORBitutil/compat.c	9 Sep 1998 04:08:14 -0000	1.4
+++ src/ORBitutil/compat.c	11 Mar 2002 12:35:58 -0000
@@ -1,24 +1,11 @@
 #include "config.h"
 #include "util.h"
 
-#define MAX_IOVS 16
-
-int g_writev(int fd, const struct  iovec *  vector,  size_t count)
-{
-  int retval = 0;
-
-  while(count > MAX_IOVS) {
-    retval += writev(fd, vector, MAX_IOVS);
-    vector += MAX_IOVS; count -= MAX_IOVS;
-  }
-
-  return writev(fd, vector, count) + retval;
-}
-
 #ifndef HAVE_INET_ATON
 #include <netinet/in.h>
 #include <string.h>
-int inet_aton(const char *cp, struct in_addr *inp)
+int
+inet_aton(const char *cp, struct in_addr *inp)
 {
 	union {
 		unsigned int n;
-- 
 mmeeks@gnu.org  <><, Pseudo Engineer, itinerant idiot




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