Skip to content

Commit

Permalink
partially revert "window_size: explicit adjustments only"
Browse files Browse the repository at this point in the history
This partially reverts commit 03ca902
in order to fix extreme slowdown when uploading to localhost via SFTP.

I was able to repeat the issue on RHEL-7 on localhost only.  It did not
occur when uploading via network and it did not occur on a RHEL-6 box
with the same version of libssh2.

The problem was that sftp_read() used a read-ahead logic to figure out
the window_size, but sftp_packet_read() called indirectly from
sftp_write() did not use any read-ahead logic.
  • Loading branch information
kdudka authored and bagder committed Sep 7, 2013
1 parent e6c46cc commit 61e40a3
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,15 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
channel->read_state = libssh2_NB_state_created;
}

/*
* =============================== 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_window_adjust;
}

rc = 1; /* set to >0 to let the while loop start */

/* Process all pending incoming packets in all states in order to "even
Expand Down Expand Up @@ -1868,6 +1877,27 @@ 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_window_adjust:
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)
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;
}

Expand Down

0 comments on commit 61e40a3

Please sign in to comment.