On Tue, 6 Sep 2011, liuzl wrote:
When sending a internal packet(eg:window adjust packet),
even we may blocked in the last call, try to send it normally
Isn't the bug in the channel_read function "only" that the adjust window
functionality breaks when transport_recv() is called until EGAIN in subsequent
calls?
I suggest the attached patch instead of yours. It makes sure that the
window_adjust function is called again immediately if it was that function
that caused the previous EAGAIN return code.
--
/ daniel.haxx.se
From 81bdcf61f38f4a3e532c17d915b2b32a27bee52b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <dan...@haxx.se>
Date: Thu, 8 Sep 2011 14:25:25 +0200
Subject: [PATCH] _libssh2_channel_read: fix non-blocking window adjusting
If EAGAIN is returned when adjusting the receive window, we must not
read from the transport directly until we've finished the adjusting.
---
src/channel.c | 21 +++++++++++----------
1 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/src/channel.c b/src/channel.c
index be6a680..75b47a5 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1754,6 +1754,16 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
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
@@ -1765,15 +1775,6 @@ 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;
- }
-
read_packet = _libssh2_list_first(&session->packets);
while (read_packet && (bytes_read < (int) buflen)) {
/* previously this loop condition also checked for
@@ -1874,7 +1875,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
if(channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30)) {
/* the window is getting too narrow, expand it! */
- channel_read_ex_point1:
+ 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 */
--
1.7.5.4
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel