Subject: [PATCH] Send internal packet priority

[PATCH] Send internal packet priority

From: liuzl <xieepp_at_gmail.com>
Date: Tue, 6 Sep 2011 09:56:47 +0800

When sending a internal packet(eg:window adjust packet),
even we may blocked in the last call, try to send it normally

Signed-off-by: liuzl <xieepp_at_gmail.com>

---
 src/channel.c   |   37 +++++++------------------------------
 src/transport.c |   12 +++++++++++-
 2 files changed, 18 insertions(+), 31 deletions(-)
diff --git a/src/channel.c b/src/channel.c
index be6a680..c1e6cb0 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1585,7 +1585,6 @@ _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,
                               "Unable to send transfer-window adjustment "
                               "packet, deferring");
@@ -1746,6 +1745,13 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
     LIBSSH2_PACKET *read_packet;
     LIBSSH2_PACKET *read_next;
 
+    if(channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30)) {
+        /* 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);
+    }
+
     if (channel->read_state == libssh2_NB_state_idle) {
         _libssh2_debug(session, LIBSSH2_TRACE_CONN,
                        "channel_read() wants %d bytes from channel %lu/%lu "
@@ -1765,15 +1771,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
@@ -1871,26 +1868,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;
 }
 
diff --git a/src/transport.c b/src/transport.c
index 057dcf5..7eecd25 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -596,7 +596,12 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
     }
 
     /* send as much as possible of the existing packet */
-    if ((data != p->odata) || (data_len != p->olen)) {
+    /* Very common scene: We may send receive-window-adjust packet at any time,
+       if we just blocked in the last call, will lead to LIBSSH2_ERROR_BAD_USE.
+       So, if the caller is an internal function, we try to send normally. This
+       behavior will be modified in the future. */
+    if (data[0] == SSH_MSG_CHANNEL_DATA && p->odata[0] == SSH_MSG_CHANNEL_DATA
+        && ((data != p->odata) || (data_len != p->olen))) {
         /* When we are about to complete the sending of a packet, it is vital
            that the caller doesn't try to send a new/different packet since
            we don't add this one up until the previous one has been sent. To
@@ -624,6 +629,11 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
     }
 
     if (rc == length) {
+        /* The existing data have been sent completely, tell parent to continue
+           sending the new data. */
+        if ((data != p->odata) || (data_len != p->olen))
+            *ret = 0;
+
         /* the remainder of the package was sent */
         p->ototal_num = 0;
         p->olen = 0;
-- 
1.7.4.msysgit.0
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2011-09-06