comparison common-channel.c @ 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 acf444bcb115
comparison
equal deleted inserted replaced
1074:10f198d4a308 1075:cc6116cc0b5c
471 iov[io_count].iov_base = (void*)moredata; 471 iov[io_count].iov_base = (void*)moredata;
472 iov[io_count].iov_len = *morelen; 472 iov[io_count].iov_len = *morelen;
473 io_count++; 473 io_count++;
474 } 474 }
475 475
476 if (io_count == 0) {
477 /* writechannel may sometimes be called twice in a main loop iteration.
478 From common_recv_msg_channel_data() then channelio().
479 The second call may not have any data to write, so we just return. */
480 TRACE(("leave writechannel, no data"))
481 return;
482 }
483
476 if (morelen) { 484 if (morelen) {
477 /* Default return value, none consumed */ 485 /* Default return value, none consumed */
478 *morelen = 0; 486 *morelen = 0;
479 } 487 }
480 488
481 written = writev(fd, iov, io_count); 489 written = writev(fd, iov, io_count);
482 490
483 if (written < 0) { 491 if (written < 0) {
484 if (errno != EINTR && errno != EAGAIN) { 492 if (errno != EINTR && errno != EAGAIN) {
485 TRACE(("errno %d", errno)) 493 TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
486 close_chan_fd(channel, fd, SHUT_WR); 494 close_chan_fd(channel, fd, SHUT_WR);
487 } 495 }
488 } else { 496 } else {
489 int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written); 497 int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written);
490 cbuf_incrread(cbuf, cbuf_written); 498 cbuf_incrread(cbuf, cbuf_written);
828 836
829 dropbear_assert(channel->recvwindow >= datalen); 837 dropbear_assert(channel->recvwindow >= datalen);
830 channel->recvwindow -= datalen; 838 channel->recvwindow -= datalen;
831 dropbear_assert(channel->recvwindow <= opts.recv_window); 839 dropbear_assert(channel->recvwindow <= opts.recv_window);
832 840
841 /* Attempt to write the data immediately without having to put it in the circular buffer */
833 consumed = datalen; 842 consumed = datalen;
834 writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed); 843 writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed);
835 844
836 datalen -= consumed; 845 datalen -= consumed;
837 buf_incrpos(ses.payload, consumed); 846 buf_incrpos(ses.payload, consumed);