Handle the error code LIBSSH2_ERROR_BAD_USE correctly,
avoid the receive window reduce to zero.
Signed-off-by: liuzl <xieepp_at_gmail.com>
--- src/channel.c | 54 +++++++++++++++++++++++++----------------------------- 1 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/channel.c b/src/channel.c index be6a680..2cbe934 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1585,8 +1585,7 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, return rc; } else if (rc) { - channel->adjust_queue = adjustment; - return _libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, + return _libssh2_error(channel->session, rc, "Unable to send transfer-window adjustment " "packet, deferring"); } @@ -1765,13 +1764,12 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) return _libssh2_error(session, rc, "transport read"); - /* - * =============================== NOTE =============================== - * I know this is very ugly and not a really good use of "goto", but - * this case statement would be even uglier to do it any other way - */ - if (channel->read_state == libssh2_NB_state_jump1) { - goto channel_read_ex_point1; + if (channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30) + && channel->adjust_state == libssh2_NB_state_idle) { + /* the window is getting too narrow, expand it! + Ignore all the sending errors since we are receiving. */ + _libssh2_channel_receive_window_adjust(channel, + (LIBSSH2_CHANNEL_WINDOW_DEFAULT*60), 0, NULL); } read_packet = _libssh2_list_first(&session->packets); @@ -1871,26 +1869,6 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, more off the network again */ channel->read_state = libssh2_NB_state_created; - if(channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30)) { - /* the window is getting too narrow, expand it! */ - - channel_read_ex_point1: - channel->read_state = libssh2_NB_state_jump1; - /* the actual window adjusting may not finish so we need to deal with - this special state here */ - rc = _libssh2_channel_receive_window_adjust(channel, - (LIBSSH2_CHANNEL_WINDOW_DEFAULT*60), 0, NULL); - if (rc == LIBSSH2_ERROR_EAGAIN) - return rc; - - _libssh2_debug(session, LIBSSH2_TRACE_CONN, - "channel_read() filled %d adjusted %d", - bytes_read, buflen); - /* continue in 'created' state to drain the already read packages - first before starting to empty the socket further */ - channel->read_state = libssh2_NB_state_created; - } - return bytes_read; } @@ -1996,6 +1974,24 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, if(buflen > 32700) buflen = 32700; + /* The previous receive window adjust failed, try again. */ + if (channel->adjust_state == libssh2_NB_state_created) { + /* Adjust the receive window size as soon as we can. */ + rc = _libssh2_channel_receive_window_adjust(channel, + (LIBSSH2_CHANNEL_WINDOW_DEFAULT*60), 0, NULL); + + /* Logic error, we will try again next time. */ + if (rc == LIBSSH2_ERROR_BAD_USE) { + _libssh2_error(channel->session, rc, + "Unable to send transfer-window adjustment packet in " + "_libssh2_channel_write(), deferring"); + } + /* Block or really socket error. */ + else if (rc < 0){ + return rc; + } + } + if (channel->write_state == libssh2_NB_state_idle) { unsigned char *s = channel->write_packet; -- 1.7.4.msysgit.0 _______________________________________________ libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-develReceived on 2011-08-31