[vlc-commits] http: track H2 stream send window

Rémi Denis-Courmont git at videolan.org
Tue Sep 24 21:00:46 CEST 2019


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Sep 22 18:03:26 2019 +0300| [ae84c42bb1416cae49d116b7f3f767be59fdaef3] | committer: Rémi Denis-Courmont

http: track H2 stream send window

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ae84c42bb1416cae49d116b7f3f767be59fdaef3
---

 modules/access/http/h2conn.c       | 22 ++++++++++++++++++++++
 modules/access/http/h2frame.c      |  7 +++++++
 modules/access/http/h2frame.h      |  1 +
 modules/access/http/h2frame_test.c |  7 +++++++
 4 files changed, 37 insertions(+)

diff --git a/modules/access/http/h2conn.c b/modules/access/http/h2conn.c
index e71bca305c..e2c9de6e86 100644
--- a/modules/access/http/h2conn.c
+++ b/modules/access/http/h2conn.c
@@ -83,6 +83,8 @@ struct vlc_h2_stream
     struct vlc_h2_frame *recv_head; /**< Earliest pending received buffer */
     struct vlc_h2_frame **recv_tailp; /**< Tail of receive queue */
     vlc_cond_t recv_wait;
+
+    uint64_t send_cwnd; /**< Send congestion window */
 };
 
 static int vlc_h2_conn_queue(struct vlc_h2_conn *conn, struct vlc_h2_frame *f)
@@ -212,6 +214,21 @@ static int vlc_h2_stream_reset(void *ctx, uint_fast32_t code)
     return 0;
 }
 
+/** Reports remote window size increments */
+static void vlc_h2_stream_window_update(void *ctx, uint_fast32_t credit)
+{
+    struct vlc_h2_stream *s = ctx;
+
+    /* In the extremely unlikely event of an overflow, the window will be
+     * treated as negative, and we will stop sending: the peer is definitely
+     * insanely broken anyway.
+     */
+    s->send_cwnd += credit;
+
+    vlc_http_dbg(SO(s), "stream %"PRIu32" window update: +%"PRIuFAST32" to "
+                 "%"PRIu64, s->id, credit, s->send_cwnd);
+}
+
 static void vlc_h2_stream_wake_up(void *data)
 {
     struct vlc_h2_stream *s = data;
@@ -418,6 +435,7 @@ static struct vlc_http_stream *vlc_h2_stream_open(struct vlc_http_conn *c,
     s->recv_head = NULL;
     s->recv_tailp = &s->recv_head;
     vlc_cond_init(&s->recv_wait);
+    s->send_cwnd = conn->init_send_cwnd;
 
     vlc_mutex_lock(&conn->lock);
     assert(!conn->released); /* Caller is buggy! */
@@ -460,6 +478,9 @@ static void vlc_h2_initial_window_update(struct vlc_h2_conn *conn,
 
     conn->init_send_cwnd = value;
     conn->send_cwnd += delta;
+
+    for (struct vlc_h2_stream *s = conn->streams; s != NULL; s = s->older)
+        s->send_cwnd += delta;
 }
 
 /** Reports an HTTP/2 peer connection setting */
@@ -570,6 +591,7 @@ static const struct vlc_h2_parser_cbs vlc_h2_parser_callbacks =
     vlc_h2_stream_data,
     vlc_h2_stream_end,
     vlc_h2_stream_reset,
+    vlc_h2_stream_window_update,
 };
 
 /**
diff --git a/modules/access/http/h2frame.c b/modules/access/http/h2frame.c
index 4bb2c6472c..dac0fbf659 100644
--- a/modules/access/http/h2frame.c
+++ b/modules/access/http/h2frame.c
@@ -876,6 +876,13 @@ static int vlc_h2_parse_frame_window_update(struct vlc_h2_parser *p,
 
     if (id == 0)
         p->cbs->window_update(p->opaque, credit);
+    else
+    {
+        void *s = vlc_h2_stream_lookup(p, id);
+
+        if (s != NULL)
+            p->cbs->stream_window_update(s, credit);
+    }
     return 0;
 }
 
diff --git a/modules/access/http/h2frame.h b/modules/access/http/h2frame.h
index 1dd8b75819..9738a32e42 100644
--- a/modules/access/http/h2frame.h
+++ b/modules/access/http/h2frame.h
@@ -114,6 +114,7 @@ struct vlc_h2_parser_cbs
     int  (*stream_data)(void *ctx, struct vlc_h2_frame *f);
     void (*stream_end)(void *ctx);
     int  (*stream_reset)(void *ctx, uint_fast32_t code);
+    void (*stream_window_update)(void *ctx, uint_fast32_t credit);
 };
 
 struct vlc_h2_parser *vlc_h2_parse_init(void *ctx,
diff --git a/modules/access/http/h2frame_test.c b/modules/access/http/h2frame_test.c
index 878026b8ca..88813ff87c 100644
--- a/modules/access/http/h2frame_test.c
+++ b/modules/access/http/h2frame_test.c
@@ -227,6 +227,12 @@ static int vlc_h2_stream_reset(void *ctx, uint_fast32_t code)
     return 0;
 }
 
+static void vlc_h2_stream_window_update(void *ctx, uint_fast32_t credit)
+{
+    assert(ctx == &stream_cookie);
+    (void) credit;
+}
+
 /* Frame formatting */
 static struct vlc_h2_frame *resize(struct vlc_h2_frame *f, size_t size)
 {   /* NOTE: increasing size would require realloc() */
@@ -341,6 +347,7 @@ static const struct vlc_h2_parser_cbs vlc_h2_frame_test_callbacks =
     vlc_h2_stream_data,
     vlc_h2_stream_end,
     vlc_h2_stream_reset,
+    vlc_h2_stream_window_update,
 };
 
 static unsigned test_seq(void *ctx, ...)



More information about the vlc-commits mailing list