mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-23 14:51:27 +02:00
MEDIUM: mux-h1: merge recv_wait and send_wait
This is the same principle as previous commit, but for the H1 mux this time. The checks in the subscribe()/unsubscribe() calls were factored and some BUG_ON() were added to detect unexpected cases. h1_wake_for_recv() and h1_wake_for_send() needed to be refined to consider the current subscription before deciding to wake up.
This commit is contained in:
parent
113d52bfb4
commit
1b0d4d19fc
81
src/mux_h1.c
81
src/mux_h1.c
@ -102,8 +102,7 @@ struct h1s {
|
|||||||
struct cs_info csinfo; /* CS info, only used for client connections */
|
struct cs_info csinfo; /* CS info, only used for client connections */
|
||||||
uint32_t flags; /* Connection flags: H1S_F_* */
|
uint32_t flags; /* Connection flags: H1S_F_* */
|
||||||
|
|
||||||
struct wait_event *recv_wait; /* Address of the wait_event the conn_stream associated is waiting on */
|
struct wait_event *subs; /* Address of the wait_event the conn_stream associated is waiting on */
|
||||||
struct wait_event *send_wait; /* Address of the wait_event the conn_stream associated is waiting on */
|
|
||||||
|
|
||||||
struct session *sess; /* Associated session */
|
struct session *sess; /* Associated session */
|
||||||
struct h1m req;
|
struct h1m req;
|
||||||
@ -523,8 +522,7 @@ static struct h1s *h1s_create(struct h1c *h1c, struct conn_stream *cs, struct se
|
|||||||
h1s->cs = NULL;
|
h1s->cs = NULL;
|
||||||
h1s->flags = H1S_F_WANT_KAL;
|
h1s->flags = H1S_F_WANT_KAL;
|
||||||
|
|
||||||
h1s->recv_wait = NULL;
|
h1s->subs = NULL;
|
||||||
h1s->send_wait = NULL;
|
|
||||||
|
|
||||||
h1m_init_req(&h1s->req);
|
h1m_init_req(&h1s->req);
|
||||||
h1s->req.flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
|
h1s->req.flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
|
||||||
@ -601,10 +599,8 @@ static void h1s_destroy(struct h1s *h1s)
|
|||||||
TRACE_POINT(H1_EV_H1S_END, h1c->conn, h1s);
|
TRACE_POINT(H1_EV_H1S_END, h1c->conn, h1s);
|
||||||
h1c->h1s = NULL;
|
h1c->h1s = NULL;
|
||||||
|
|
||||||
if (h1s->recv_wait != NULL)
|
if (h1s->subs)
|
||||||
h1s->recv_wait->events &= ~SUB_RETRY_RECV;
|
h1s->subs->events = 0;
|
||||||
if (h1s->send_wait != NULL)
|
|
||||||
h1s->send_wait->events &= ~SUB_RETRY_SEND;
|
|
||||||
|
|
||||||
h1c->flags &= ~H1C_F_IN_BUSY;
|
h1c->flags &= ~H1C_F_IN_BUSY;
|
||||||
if (h1s->flags & (H1S_F_REQ_ERROR|H1S_F_RES_ERROR)) {
|
if (h1s->flags & (H1S_F_REQ_ERROR|H1S_F_RES_ERROR)) {
|
||||||
@ -1960,20 +1956,22 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
static void h1_wake_stream_for_recv(struct h1s *h1s)
|
static void h1_wake_stream_for_recv(struct h1s *h1s)
|
||||||
{
|
{
|
||||||
if (h1s && h1s->recv_wait) {
|
if (h1s && h1s->subs && h1s->subs->events & SUB_RETRY_RECV) {
|
||||||
TRACE_POINT(H1_EV_STRM_WAKE, h1s->h1c->conn, h1s);
|
TRACE_POINT(H1_EV_STRM_WAKE, h1s->h1c->conn, h1s);
|
||||||
h1s->recv_wait->events &= ~SUB_RETRY_RECV;
|
tasklet_wakeup(h1s->subs->tasklet);
|
||||||
tasklet_wakeup(h1s->recv_wait->tasklet);
|
h1s->subs->events &= ~SUB_RETRY_RECV;
|
||||||
h1s->recv_wait = NULL;
|
if (!h1s->subs->events)
|
||||||
|
h1s->subs = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void h1_wake_stream_for_send(struct h1s *h1s)
|
static void h1_wake_stream_for_send(struct h1s *h1s)
|
||||||
{
|
{
|
||||||
if (h1s && h1s->send_wait) {
|
if (h1s && h1s->subs && h1s->subs->events & SUB_RETRY_SEND) {
|
||||||
TRACE_POINT(H1_EV_STRM_WAKE, h1s->h1c->conn, h1s);
|
TRACE_POINT(H1_EV_STRM_WAKE, h1s->h1c->conn, h1s);
|
||||||
h1s->send_wait->events &= ~SUB_RETRY_SEND;
|
tasklet_wakeup(h1s->subs->tasklet);
|
||||||
tasklet_wakeup(h1s->send_wait->tasklet);
|
h1s->subs->events &= ~SUB_RETRY_SEND;
|
||||||
h1s->send_wait = NULL;
|
if (!h1s->subs->events)
|
||||||
|
h1s->subs = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2547,54 +2545,51 @@ static void h1_shutw_conn(struct connection *conn, enum cs_shw_mode mode)
|
|||||||
/* Called from the upper layer, to unsubscribe to events */
|
/* Called from the upper layer, to unsubscribe to events */
|
||||||
static int h1_unsubscribe(struct conn_stream *cs, int event_type, void *param)
|
static int h1_unsubscribe(struct conn_stream *cs, int event_type, void *param)
|
||||||
{
|
{
|
||||||
struct wait_event *sw;
|
struct wait_event *sw = param;
|
||||||
struct h1s *h1s = cs->ctx;
|
struct h1s *h1s = cs->ctx;
|
||||||
|
|
||||||
if (!h1s)
|
if (!h1s)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (event_type & SUB_RETRY_RECV) {
|
BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV));
|
||||||
|
BUG_ON(h1s->subs && h1s->subs != sw);
|
||||||
|
|
||||||
|
sw->events &= ~event_type;
|
||||||
|
if (!sw->events)
|
||||||
|
h1s->subs = NULL;
|
||||||
|
|
||||||
|
if (event_type & SUB_RETRY_RECV)
|
||||||
TRACE_DEVEL("unsubscribe(recv)", H1_EV_STRM_RECV, h1s->h1c->conn, h1s);
|
TRACE_DEVEL("unsubscribe(recv)", H1_EV_STRM_RECV, h1s->h1c->conn, h1s);
|
||||||
sw = param;
|
|
||||||
BUG_ON(h1s->recv_wait != sw);
|
if (event_type & SUB_RETRY_SEND)
|
||||||
sw->events &= ~SUB_RETRY_RECV;
|
|
||||||
h1s->recv_wait = NULL;
|
|
||||||
}
|
|
||||||
if (event_type & SUB_RETRY_SEND) {
|
|
||||||
TRACE_DEVEL("unsubscribe(send)", H1_EV_STRM_SEND, h1s->h1c->conn, h1s);
|
TRACE_DEVEL("unsubscribe(send)", H1_EV_STRM_SEND, h1s->h1c->conn, h1s);
|
||||||
sw = param;
|
|
||||||
BUG_ON(h1s->send_wait != sw);
|
|
||||||
sw->events &= ~SUB_RETRY_SEND;
|
|
||||||
h1s->send_wait = NULL;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from the upper layer, to subscribe to events, such as being able to send */
|
/* Called from the upper layer, to subscribe to events, such as being able to send */
|
||||||
static int h1_subscribe(struct conn_stream *cs, int event_type, void *param)
|
static int h1_subscribe(struct conn_stream *cs, int event_type, void *param)
|
||||||
{
|
{
|
||||||
struct wait_event *sw;
|
struct wait_event *sw = param;
|
||||||
struct h1s *h1s = cs->ctx;
|
struct h1s *h1s = cs->ctx;
|
||||||
struct h1c *h1c;
|
struct h1c *h1c;
|
||||||
|
|
||||||
if (!h1s)
|
if (!h1s)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (event_type & SUB_RETRY_RECV) {
|
BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV));
|
||||||
|
BUG_ON(h1s->subs && h1s->subs->events & event_type);
|
||||||
|
BUG_ON(h1s->subs && h1s->subs != sw);
|
||||||
|
|
||||||
|
sw->events |= event_type;
|
||||||
|
h1s->subs = sw;
|
||||||
|
|
||||||
|
if (event_type & SUB_RETRY_RECV)
|
||||||
TRACE_DEVEL("subscribe(recv)", H1_EV_STRM_RECV, h1s->h1c->conn, h1s);
|
TRACE_DEVEL("subscribe(recv)", H1_EV_STRM_RECV, h1s->h1c->conn, h1s);
|
||||||
sw = param;
|
|
||||||
BUG_ON(h1s->recv_wait != NULL || (sw->events & SUB_RETRY_RECV));
|
|
||||||
sw->events |= SUB_RETRY_RECV;
|
|
||||||
h1s->recv_wait = sw;
|
|
||||||
event_type &= ~SUB_RETRY_RECV;
|
|
||||||
}
|
|
||||||
if (event_type & SUB_RETRY_SEND) {
|
if (event_type & SUB_RETRY_SEND) {
|
||||||
TRACE_DEVEL("subscribe(send)", H1_EV_STRM_SEND, h1s->h1c->conn, h1s);
|
TRACE_DEVEL("subscribe(send)", H1_EV_STRM_SEND, h1s->h1c->conn, h1s);
|
||||||
sw = param;
|
|
||||||
BUG_ON(h1s->send_wait != NULL || (sw->events & SUB_RETRY_SEND));
|
|
||||||
sw->events |= SUB_RETRY_SEND;
|
|
||||||
h1s->send_wait = sw;
|
|
||||||
event_type &= ~SUB_RETRY_SEND;
|
|
||||||
/*
|
/*
|
||||||
* If the conn_stream attempt to subscribe, and the
|
* If the conn_stream attempt to subscribe, and the
|
||||||
* mux isn't subscribed to the connection, then it
|
* mux isn't subscribed to the connection, then it
|
||||||
@ -2608,8 +2603,6 @@ static int h1_subscribe(struct conn_stream *cs, int event_type, void *param)
|
|||||||
SUB_RETRY_SEND,
|
SUB_RETRY_SEND,
|
||||||
&h1c->wait_event);
|
&h1c->wait_event);
|
||||||
}
|
}
|
||||||
if (event_type != 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user