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