]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: h2: Don't attempt to recv from h2_process_demux if we subscribed.
authorOlivier Houchard <ohouchard@haproxy.com>
Fri, 5 Apr 2019 13:34:34 +0000 (15:34 +0200)
committerOlivier Houchard <cognet@ci0.org>
Fri, 5 Apr 2019 14:03:54 +0000 (16:03 +0200)
Modify h2c_restart_reading() to add a new parameter, to let it know if it
should consider if the buffer isn't empty when retrying to read or not, and
call h2c_restart_reading() using 0 as a parameter from h2_process_demux().
If we're leaving h2_process_demux() with a non-empty buffer, it means the
frame is incomplete, and we're waiting for more data, and if we already
subscribed, we'll be waken when more data are available.
Failing to do so means we'll be waken up in a loop until more data are
available.

This should be backported to 1.9.

src/mux_h2.c

index 9894592e58a02b24776146bd610e45ff937863d4..76343613a198cd03c0034cbece7034f459c763db 100644 (file)
@@ -332,11 +332,12 @@ static inline int h2_recv_allowed(const struct h2c *h2c)
 }
 
 /* restarts reading on the connection if it was not enabled */
-static inline void h2c_restart_reading(const struct h2c *h2c)
+static inline void h2c_restart_reading(const struct h2c *h2c, int consider_buffer)
 {
        if (!h2_recv_allowed(h2c))
                return;
-       if (!b_data(&h2c->dbuf) && (h2c->wait_event.events & SUB_RETRY_RECV))
+       if ((!consider_buffer || !b_data(&h2c->dbuf))
+           && (h2c->wait_event.events & SUB_RETRY_RECV))
                return;
        tasklet_wakeup(h2c->wait_event.task);
 }
@@ -360,7 +361,7 @@ static int h2_buf_available(void *target)
 
        if ((h2c->flags & H2_CF_DEM_DALLOC) && b_alloc_margin(&h2c->dbuf, 0)) {
                h2c->flags &= ~H2_CF_DEM_DALLOC;
-               h2c_restart_reading(h2c);
+               h2c_restart_reading(h2c, 1);
                return 1;
        }
 
@@ -369,7 +370,7 @@ static int h2_buf_available(void *target)
 
                if (h2c->flags & H2_CF_DEM_MROOM) {
                        h2c->flags &= ~H2_CF_DEM_MROOM;
-                       h2c_restart_reading(h2c);
+                       h2c_restart_reading(h2c, 1);
                }
                return 1;
        }
@@ -378,7 +379,7 @@ static int h2_buf_available(void *target)
            (h2s = h2c_st_by_id(h2c, h2c->dsi)) && h2s->cs &&
            b_alloc_margin(&h2s->rxbuf, 0)) {
                h2c->flags &= ~H2_CF_DEM_SALLOC;
-               h2c_restart_reading(h2c);
+               h2c_restart_reading(h2c, 1);
                return 1;
        }
 
@@ -567,7 +568,7 @@ static int h2_init(struct connection *conn, struct proxy *prx, struct session *s
        conn->ctx = h2c;
 
        /* prepare to read something */
-       h2c_restart_reading(h2c);
+       h2c_restart_reading(h2c, 1);
        return 0;
   fail_stream:
        hpack_dht_free(h2c->ddht);
@@ -2529,7 +2530,7 @@ static void h2_process_demux(struct h2c *h2c)
                h2s_notify_recv(h2s);
        }
 
-       h2c_restart_reading(h2c);
+       h2c_restart_reading(h2c, 0);
 }
 
 /* process Tx frames from streams to be multiplexed. Returns > 0 if it reached
@@ -3011,7 +3012,7 @@ static void h2_detach(struct conn_stream *cs)
            !h2_frt_has_too_many_cs(h2c)) {
                /* frontend connection was blocking new streams creation */
                h2c->flags &= ~H2_CF_DEM_TOOMANY;
-               h2c_restart_reading(h2c);
+               h2c_restart_reading(h2c, 1);
        }
 
        /* this stream may be blocked waiting for some data to leave (possibly
@@ -3029,7 +3030,7 @@ static void h2_detach(struct conn_stream *cs)
                 */
                h2c->flags &= ~H2_CF_DEM_BLOCK_ANY;
                h2c->flags &= ~H2_CF_MUX_BLOCK_ANY;
-               h2c_restart_reading(h2c);
+               h2c_restart_reading(h2c, 1);
        }
 
        h2s_destroy(h2s);
@@ -5258,7 +5259,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
        if (ret && h2c->dsi == h2s->id) {
                /* demux is blocking on this stream's buffer */
                h2c->flags &= ~H2_CF_DEM_SFULL;
-               h2c_restart_reading(h2c);
+               h2c_restart_reading(h2c, 1);
        }
 
        return ret;