IIOP fix because unix io sucks



giop_send_buffer_write wasn't looping on partial writes, so it would
lose on anything with a BSD-derived network stack if you tried to
write a buffer larger than 8192 bytes.

(This patch is required to make evolution work on BSD.)

Index: src/IIOP/giop-msg-buffer.c
===================================================================
RCS file: /cvs/gnome/ORBit/src/IIOP/giop-msg-buffer.c,v
retrieving revision 1.117.4.4
diff -u -w -r1.117.4.4 giop-msg-buffer.c
--- src/IIOP/giop-msg-buffer.c	2000/11/15 02:10:36	1.117.4.4
+++ src/IIOP/giop-msg-buffer.c	2001/03/07 18:37:11
@@ -173,11 +173,12 @@
 giop_send_buffer_write(GIOPSendBuffer *send_buffer)
 {
   gulong nvecs;
-  glong res, sum, t;
+  glong res, wrote, sum, t;
   struct iovec *curvec;
   int fd;
   GIOPConnection *cnx;
   gint retval = -1;
+  gboolean blocking = FALSE;
 
   cnx = GIOP_MESSAGE_BUFFER(send_buffer)->connection;
   if(!cnx->is_valid)
@@ -197,19 +198,27 @@
 	    sum);
   }
 #endif
-  res = writev(fd, curvec, nvecs);
 
   sum = (GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size + sizeof(GIOPMessageHeader));
-  if(res < sum) {
-    if(res < 0) {
+  res = 0;
+
+  while (res < sum) {
+    wrote = writev(fd, curvec, nvecs);
+    if(wrote < 0) {
       if(errno != EAGAIN) {
 	giop_main_handle_connection_exception(cnx);
 	goto out;
       }
 
-      res = 0;
+      fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+      blocking = TRUE;
+      continue;
     }
 
+    res += wrote;
+    if (res >= sum)
+      break;
+
     /* wrote 7, iovecs 3, 2, 2, 4:
        0 + 3 !> 7
        3 + 2 !> 7
@@ -217,29 +226,25 @@
      */
 
     for(t = 0; ; t += curvec->iov_len, curvec++, nvecs--) {
-      if((t + curvec->iov_len) > res)
+      if((t + curvec->iov_len) > wrote)
 	break;
     }
-    if((res - t) > 0) {
-      curvec->iov_len -= (res - t);
-      curvec->iov_base = (gpointer)((char *)curvec->iov_base + (res - t));
+    if((wrote - t) > 0) {
+      curvec->iov_len -= (wrote - t);
+      curvec->iov_base = (gpointer)((char *)curvec->iov_base + (wrote - 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)) {
+  if(res < sum) {
 	giop_main_handle_connection_exception(cnx);
 	goto out;
     }
-  }
 
   retval = 0;
 
  out:
+  if(blocking)
+    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
 
   return retval;
 }





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