diff options
author | Matt Johnston <matt@ucc.asn.au> | 2015-03-21 22:43:08 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2015-03-21 22:43:08 +0800 |
commit | ef20b9ff7a61a3619daf9d7f778d3b42c9322eb1 (patch) | |
tree | 4aa526feaea90cfaae3c1e20c6046e9d0e5b3dda | |
parent | 275611fbaaa14824de69bccc68161d5ed195b745 (diff) |
Avoid channel writev() when there is nothing to write
-rw-r--r-- | common-channel.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/common-channel.c b/common-channel.c index 0e5c0f1..6dce497 100644 --- a/common-channel.c +++ b/common-channel.c @@ -473,6 +473,14 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf, 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 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf, 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 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, 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); |