]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connections/mux: Add the wait reason(s) to wait_list.
authorOlivier Houchard <ohouchard@haproxy.com>
Wed, 1 Aug 2018 15:06:43 +0000 (17:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 16 Aug 2018 15:29:53 +0000 (17:29 +0200)
Add a new element to the wait_list, that let us know which event(s) we are
waiting on.

include/proto/connection.h
include/types/connection.h
src/connection.c
src/mux_h2.c
src/stream_interface.c

index e4621ccbdef08668adbbc56139b72a72cc4a0591..35b9dfe49d8cbeb0358ed8577d60596bb654844a 100644 (file)
@@ -601,6 +601,7 @@ static inline void cs_init(struct conn_stream *cs, struct connection *conn)
        LIST_INIT(&cs->wait_list.list);
        LIST_INIT(&cs->send_wait_list);
        cs->conn = conn;
+       cs->wait_list.wait_reason = 0;
 }
 
 /* Initializes all required fields for a new connection. Note that it does the
index abe85a477f760a3fda5f1621100b1a4b36bbc760..9a1ba9667ec2610fd15afa2b912fabe78239d2a5 100644 (file)
@@ -44,9 +44,15 @@ struct buffer;
 struct server;
 struct pipe;
 
+enum sub_event_type {
+       SUB_CAN_SEND        = 0x00000001,  /* Schedule the tasklet when we can send more */
+       SUB_CAN_RECV        = 0x00000002,  /* Schedule the tasklet when we can recv more */
+};
+
 struct wait_list {
        struct tasklet *task;
        struct list list;
+       int wait_reason;
 };
 
 /* A connection handle is how we differenciate two connections on the lower
@@ -90,9 +96,6 @@ enum cs_shw_mode {
        CS_SHW_SILENT       = 1,           /* imminent close, don't notify peer */
 };
 
-enum sub_event_type {
-       SUB_CAN_SEND        = 0x00000001,  /* Schedule the tasklet when we can send more */
-};
 /* For each direction, we have a CO_FL_{SOCK,DATA}_<DIR>_ENA flag, which
  * indicates if read or write is desired in that direction for the respective
  * layers. The current status corresponding to the current layer being used is
index df3df8426190f958f147fce1cf36011b93c7b60d..ee80e616ff2b4ed0f1670d84ec3a6ccc2553da5e 100644 (file)
@@ -134,6 +134,7 @@ void conn_fd_handler(int fd)
                            struct wait_list *, list);
                        LIST_DEL(&sw->list);
                        LIST_INIT(&sw->list);
+                       sw->wait_reason &= ~SUB_CAN_SEND;
                        tasklet_wakeup(sw->task);
                }
        }
@@ -338,8 +339,10 @@ int conn_subscribe(struct connection *conn, int event_type, void *param)
        switch (event_type) {
        case SUB_CAN_SEND:
                sw = param;
-               if (LIST_ISEMPTY(&sw->list))
+               if (!(sw->wait_reason & SUB_CAN_SEND)) {
+                       sw->wait_reason |= SUB_CAN_SEND;
                        LIST_ADDQ(&conn->send_wait_list, &sw->list);
+               }
                return 0;
        default:
                break;
index 0ad4bac20d438e86bc269314f572edc1d0c1fd26..538d21f07a787bb5ad0fb2e1f9c7d173541612e1 100644 (file)
@@ -369,6 +369,7 @@ static int h2c_frt_init(struct connection *conn)
                goto fail;
        h2c->wait_list.task->process = h2_send;
        h2c->wait_list.task->context = conn;
+       h2c->wait_list.wait_reason = 0;
 
        h2c->ddht = hpack_dht_alloc(h2_settings_header_table_size);
        if (!h2c->ddht)
@@ -2289,6 +2290,7 @@ static struct task *h2_send(struct task *t, void *ctx, unsigned short state)
                            struct wait_list *, list);
                        LIST_DEL(&sw->list);
                        LIST_INIT(&sw->list);
+                       sw->wait_reason &= ~SUB_CAN_SEND;
                        tasklet_wakeup(sw->task);
                }
 
@@ -3409,8 +3411,11 @@ static int h2_subscribe(struct conn_stream *cs, int event_type, void *param)
        switch (event_type) {
        case SUB_CAN_SEND:
                sw = param;
-               if (LIST_ISEMPTY(&h2s->list) && LIST_ISEMPTY(&sw->list))
+               if (LIST_ISEMPTY(&h2s->list) &&
+                   !(sw->wait_reason & SUB_CAN_SEND)) {
                        LIST_ADDQ(&h2s->h2c->send_wait_list, &sw->list);
+                       sw->wait_reason |= SUB_CAN_SEND;
+               }
                return 0;
        default:
                break;
index f2d6b6f5b0f593529966e13f4c7ec1708416550d..92b8e85c3d70e2c1fa483b36313363335ba41d4f 100644 (file)
@@ -652,7 +652,7 @@ static struct task * si_cs_send(struct task *t, void *ctx, unsigned short state)
        int did_send = 0;
 
        /* We're already waiting to be able to send, give up */
-       if (!LIST_ISEMPTY(&cs->wait_list.list))
+       if (cs->wait_list.wait_reason & SUB_CAN_SEND)
                return NULL;
 
        if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
@@ -661,7 +661,7 @@ static struct task * si_cs_send(struct task *t, void *ctx, unsigned short state)
        if (conn->flags & CO_FL_HANDSHAKE) {
                /* a handshake was requested */
                /* Schedule ourself to be woken up once the handshake is done */
-               LIST_ADDQ(&conn->send_wait_list, &cs->wait_list.list);
+               conn->xprt->subscribe(conn, SUB_CAN_SEND,  wl_set_waitcb(&cs->wait_list, si_cs_send, ctx));
                return NULL;
        }
 
@@ -751,6 +751,7 @@ wake_others:
                            struct wait_list *, list);
                        LIST_DEL(&sw->list);
                        LIST_INIT(&sw->list);
+                       sw->wait_reason &= ~SUB_CAN_SEND;
                        tasklet_wakeup(sw->task);
                }
        }