changeset 1075:cc6116cc0b5c

Avoid channel writev() when there is nothing to write
author Matt Johnston <matt@ucc.asn.au>
date Sat, 21 Mar 2015 22:43:08 +0800
parents 10f198d4a308
children d92597ef089e
files common-channel.c
diffstat 1 files changed, 10 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/common-channel.c	Fri Mar 20 23:36:42 2015 +0800
+++ b/common-channel.c	Sat Mar 21 22:43:08 2015 +0800
@@ -473,6 +473,14 @@
 		io_count++;
 	}
 
+	if (io_count == 0) {
+		/* writechannel may sometimes be called twice in a main loop iteration.
+		From common_recv_msg_channel_data() then channelio().
+		The second call may not have any data to write, so we just return. */
+		TRACE(("leave writechannel, no data"))
+		return;
+	}
+
 	if (morelen) {
 		/* Default return value, none consumed */
 		*morelen = 0;
@@ -482,7 +490,7 @@
 
 	if (written < 0) {
 		if (errno != EINTR && errno != EAGAIN) {
-			TRACE(("errno %d", errno))
+			TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
 			close_chan_fd(channel, fd, SHUT_WR);
 		}
 	} else {
@@ -830,6 +838,7 @@
 	channel->recvwindow -= datalen;
 	dropbear_assert(channel->recvwindow <= opts.recv_window);
 
+	/* Attempt to write the data immediately without having to put it in the circular buffer */
 	consumed = datalen;
 	writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed);