[vlc-commits] http: HTTP/2 write function

Rémi Denis-Courmont git at videolan.org
Sun Oct 4 12:26:21 CEST 2020


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Oct  3 20:26:48 2020 +0300| [e67222c6b751b7a6986f5db537faa541403155eb] | committer: Rémi Denis-Courmont

http: HTTP/2 write function

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

 modules/access/http/h2conn.c | 92 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 91 insertions(+), 1 deletion(-)

diff --git a/modules/access/http/h2conn.c b/modules/access/http/h2conn.c
index 93106cdc76..cab9610e67 100644
--- a/modules/access/http/h2conn.c
+++ b/modules/access/http/h2conn.c
@@ -282,6 +282,96 @@ static struct vlc_http_msg *vlc_h2_stream_wait(struct vlc_http_stream *stream)
     return m;
 }
 
+static ssize_t vlc_h2_stream_write(struct vlc_http_stream *stream,
+                                   const void *base, size_t length, bool eos)
+{
+    struct vlc_h2_stream *s =
+        container_of(stream, struct vlc_h2_stream, stream);
+    struct vlc_h2_conn *conn = s->conn;
+    ssize_t total = 0;
+    int err = 0;
+
+    if (unlikely(length == 0 && !eos))
+        return 0;
+
+    vlc_h2_stream_lock(s);
+    do
+    {
+        size_t size = length;
+
+        /* This and the following flow control comparison and subtraction all
+         * assumes that we do *not* use any padding on the data frames.
+         */
+        if (size > conn->max_send_frame)
+            size = conn->max_send_frame;
+
+        /* Stream flow control */
+        if (size > s->send_cwnd)
+            size = s->send_cwnd;
+        if (size == 0 && length > 0)
+        {
+            if (s->interrupted)
+            {
+                err = EINTR;
+                break;
+            }
+
+            mutex_cleanup_push(&conn->lock);
+            vlc_cond_wait(&s->send_wait, &conn->lock);
+            vlc_cleanup_pop();
+            continue;
+        }
+
+        /* Connection flow control */
+        if (size > conn->send_cwnd)
+            size = conn->send_cwnd;
+        if (size == 0 && length > 0)
+        {
+            if (s->interrupted)
+            {
+                err = EINTR;
+                break;
+            }
+
+            mutex_cleanup_push(&conn->lock);
+            vlc_cond_wait(&conn->send_wait, &conn->lock);
+            vlc_cleanup_pop();
+            continue;
+        }
+
+        /* Frame send */
+        bool end = eos && length == size;
+        struct vlc_h2_frame *f = vlc_h2_frame_data(s->id, base, size, end);
+
+        if (f == NULL)
+        {
+            err = ENOMEM;
+            break;
+        }
+
+        if (vlc_h2_conn_queue(conn, f))
+        {
+            err = ECONNRESET;
+            break;
+        }
+
+        base = (const char *)base + size;
+        length -= size;
+        total += size;
+        s->send_cwnd -= size;
+        conn->send_cwnd -= size;
+    }
+    while (length > 0);
+    vlc_h2_stream_unlock(s);
+
+    if (total == 0 && err != 0)
+    {
+        errno = err;
+        total = -1;
+    }
+    return total;
+}
+
 /**
  * Receives stream data.
  *
@@ -404,7 +494,7 @@ static void vlc_h2_stream_close(struct vlc_http_stream *stream, bool aborted)
 static const struct vlc_http_stream_cbs vlc_h2_stream_callbacks =
 {
     vlc_h2_stream_wait,
-    NULL,
+    vlc_h2_stream_write,
     vlc_h2_stream_read,
     vlc_h2_stream_close,
 };



More information about the vlc-commits mailing list