Pavlin Radoslavov wrote:

OK, given that the patch is relatively small, please try to clean it
up by eliminating the extra #ifdef and try to see if you can reduce
the code duplication when using different system calls.
I will make it a high priority for me to double-check and commit the
patch, and will leave it to the community to test it :)

Thanks, the patch is attached.  I tried to get all of the #ifdefs
in one place in the code.  This appears to work fine on
Linux, but might have to futz with it a bit to compile on
Windows, maybe by faking a #define SIGPIPE as I alluded to
in the comment.

Please let me know if you want any more changes.

Thanks,
Ben

--
Ben Greear <[EMAIL PROTECTED]>
Candela Technologies Inc  http://www.candelatech.com

Index: asyncio.cc
===================================================================
RCS file: /cvs/xorp/libxorp/asyncio.cc,v
retrieving revision 1.40
diff -u -r1.40 asyncio.cc
--- asyncio.cc	4 Jan 2008 03:16:32 -0000	1.40
+++ asyncio.cc	20 Mar 2008 23:31:56 -0000
@@ -205,8 +205,12 @@
     _last_error = 0;
     done = ::read(_fd, head->buffer() + head->offset(),
 		  head->buffer_bytes() - head->offset());
-    if (done < 0)
+    if (done < 0) {
 	_last_error = errno;
+	XLOG_WARNING("read error: _fd: %i  offset: %i  total-len: %i error: %s\n",
+		     (int)(_fd), head->offset(), head->buffer_bytes(),
+		     strerror(errno));
+    }
     errno = 0;
 #endif // ! HOST_OS_WINDOWS
 
@@ -534,6 +538,22 @@
 
     list<BufferInfo *>::const_iterator i = _buffers.begin();
 
+    // This assumes that windows will compile with SIGPIPE, but we won't
+    // actually use it.  If it won't compile, maybe just #define SIGPIPE to something
+    // that will compile, and figure it won't get called because mod_signals will be
+    // false.
+#ifndef HOST_OS_WINDOWS
+#ifndef MSG_NOSIGNAL
+    int flags = 0;
+#else
+    int flags = MSG_NOSIGNAL;
+#endif
+    bool mod_signals = !!flags;
+#else
+    bool mod_signals = false;
+    int flags = 0;
+#endif
+
     //
     // Group together a number of buffers.
     // If the buffer is sendto()-type, then send that buffer on its own.
@@ -570,9 +590,10 @@
 	//
 	XLOG_ASSERT(! dst_addr.is_zero());
 
-#ifndef HOST_OS_WINDOWS
-	sig_t saved_sigpipe = signal(SIGPIPE, SIG_IGN);
-#endif
+	sig_t saved_sigpipe;
+	if (mod_signals) {
+	    signal(SIGPIPE, SIG_IGN);
+	}
 
 	switch (dst_addr.af()) {
 	case AF_INET:
@@ -584,7 +605,7 @@
 
 	    done = ::sendto(_fd, XORP_CONST_BUF_CAST(_iov[0].iov_base),
 			    _iov[0].iov_len,
-			    0,
+			    flags,
 			    reinterpret_cast<const sockaddr*>(&sin),
 			    sizeof(sin));
 	    break;
@@ -599,7 +620,7 @@
 
 	    done = ::sendto(_fd, XORP_CONST_BUF_CAST(_iov[0].iov_base),
 			    _iov[0].iov_len,
-			    0,
+			    flags,
 			    reinterpret_cast<const sockaddr*>(&sin6),
 			    sizeof(sin6));
 	    break;
@@ -619,9 +640,9 @@
 #endif
 	}
 
-#ifndef HOST_OS_WINDOWS
-	signal(SIGPIPE, saved_sigpipe);
-#endif
+	if (mod_signals) {
+	    signal(SIGPIPE, saved_sigpipe);
+	}
 
     } else {
 	//
@@ -654,16 +675,24 @@
 	    _last_error = (result == FALSE) ? GetLastError() : 0;
 	}
 #else // ! HOST_OS_WINDOWS
-	sig_t saved_sigpipe = signal(SIGPIPE, SIG_IGN);
 
 	errno = 0;
 	_last_error = 0;
-	done = ::writev(_fd, _iov, (int)iov_cnt);
+
+	if (flags && (iov_cnt == 1)) {
+	    // No need for coelesce, so use send.  This saves us the two
+	    // sigaction calls since we can pass the MSG_NOSIGNAL flag.
+	    done = ::send(_fd, XORP_CONST_BUF_CAST(_iov[0].iov_base),
+			  _iov[0].iov_len, flags);
+	}
+	else {
+	    sig_t saved_sigpipe = signal(SIGPIPE, SIG_IGN);
+	    done = ::writev(_fd, _iov, (int)iov_cnt);
+	    signal(SIGPIPE, saved_sigpipe);
+	}
 	if (done < 0)
 	    _last_error = errno;
 	errno = 0;
-
-	signal(SIGPIPE, saved_sigpipe);
 #endif // ! HOST_OS_WINDOWS
     }
 
_______________________________________________
Xorp-hackers mailing list
[email protected]
http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers

Reply via email to