From: Willy Tarreau Date: Fri, 17 Jan 2020 06:52:13 +0000 (+0100) Subject: MINOR: connection: make the last arg of subscribe() a struct wait_event* X-Git-Tag: v2.2-dev1~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee1a6fc943ae8e3e9f79ab5d3d775062d1bf9a47;p=thirdparty%2Fhaproxy.git MINOR: connection: make the last arg of subscribe() a struct wait_event* The subscriber used to be passed as a "void *param" that was systematically cast to a struct wait_event*. By now it appears clear that the subscribe() call at every layer is well defined and always takes a pointer to an event subscriber of type wait_event, so let's enforce this in the functions' prototypes, remove the intermediary variables used to cast it and clean up the comments to clarify what all these functions do in their context. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 7e6e20320a..b0771cbf9d 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -51,8 +51,8 @@ int make_proxy_line(char *buf, int buf_len, struct server *srv, struct connectio int make_proxy_line_v1(char *buf, int buf_len, struct sockaddr_storage *src, struct sockaddr_storage *dst); int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connection *remote); -int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param); -int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param); +int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); +int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); /* receive a NetScaler Client IP insertion header over a connection */ int conn_recv_netscaler_cip(struct connection *conn, int flag); diff --git a/include/types/connection.h b/include/types/connection.h index 060588ff8e..4524c2e955 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -326,8 +326,8 @@ struct xprt_ops { void (*destroy_srv)(struct server *srv); /* destroy a server context */ int (*get_alpn)(const struct connection *conn, void *xprt_ctx, const char **str, int *len); /* get application layer name */ char name[8]; /* transport layer name, zero-terminated */ - int (*subscribe)(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* Subscribe to events, such as "being able to send" */ - int (*unsubscribe)(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* Unsubscribe to events */ + int (*subscribe)(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); /* Subscribe to events, such as "being able to send" */ + int (*unsubscribe)(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); /* Unsubscribe from events */ int (*remove_xprt)(struct connection *conn, void *xprt_ctx, void *toremove_ctx, const struct xprt_ops *newops, void *newctx); /* Remove an xprt from the connection, used by temporary xprt such as the handshake one */ int (*add_xprt)(struct connection *conn, void *xprt_ctx, void *toadd_ctx, const struct xprt_ops *toadd_ops, void **oldxprt_ctx, const struct xprt_ops **oldxprt_ops); /* Add a new XPRT as the new xprt, and return the old one */ }; @@ -359,8 +359,8 @@ struct mux_ops { const struct conn_stream *(*get_first_cs)(const struct connection *); /* retrieves any valid conn_stream from this connection */ void (*detach)(struct conn_stream *); /* Detach a conn_stream from an outgoing connection, when the request is done */ void (*show_fd)(struct buffer *, struct connection *); /* append some data about connection into chunk for "show fd" */ - int (*subscribe)(struct conn_stream *cs, int event_type, void *param); /* Subscribe to events, such as "being able to send" */ - int (*unsubscribe)(struct conn_stream *cs, int event_type, void *param); /* Unsubscribe to events */ + int (*subscribe)(struct conn_stream *cs, int event_type, struct wait_event *es); /* Subscribe to events, such as "being able to send" */ + int (*unsubscribe)(struct conn_stream *cs, int event_type, struct wait_event *es); /* Unsubscribe from events */ int (*avail_streams)(struct connection *conn); /* Returns the number of streams still available for a connection */ int (*used_streams)(struct connection *conn); /* Returns the number of streams in use on a connection. */ void (*destroy)(void *ctx); /* Let the mux know one of its users left, so it may have to disappear */ diff --git a/src/connection.c b/src/connection.c index a0524ad847..580aa3313b 100644 --- a/src/connection.c +++ b/src/connection.c @@ -322,15 +322,18 @@ int conn_sock_send(struct connection *conn, const void *buf, int len, int flags) return ret; } -int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0. + */ +int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { - struct wait_event *sw = param; - BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); - BUG_ON(conn->subs && conn->subs != sw); + BUG_ON(conn->subs && conn->subs != es); - sw->events &= ~event_type; - if (!sw->events) + es->events &= ~event_type; + if (!es->events) conn->subs = NULL; if (event_type & SUB_RETRY_RECV) @@ -343,16 +346,18 @@ int conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, vo return 0; } -int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to unsubscribe from events + * (undo fcgi_subscribe). The struct is not allowed to differ from the one + * passed to the subscribe() call. It always returns zero. + */ +int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { - struct wait_event *sw = param; - BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); BUG_ON(conn->subs && conn->subs->events & event_type); - BUG_ON(conn->subs && conn->subs != sw); + BUG_ON(conn->subs && conn->subs != es); - conn->subs = sw; - sw->events |= event_type; + conn->subs = es; + es->events |= event_type; if (event_type & SUB_RETRY_RECV) __conn_xprt_want_recv(conn); diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index 8e98f1b1e4..09d3575121 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -3695,24 +3695,22 @@ static void fcgi_shutw(struct conn_stream *cs, enum cs_shw_mode mode) fcgi_do_shutw(fstrm); } -/* Called from the upper layer, to subscribe to events, such as being able to send. - * The argument here is supposed to be a pointer to a wait_event struct - * which will be passed to fstrm->subs. The event_type must only be a - * combination of SUB_RETRY_RECV and SUB_RETRY_SEND, other values will lead to -1 - * being returned. It always returns 0 except for the error above. +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0. */ -static int fcgi_subscribe(struct conn_stream *cs, int event_type, void *param) +static int fcgi_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct fcgi_strm *fstrm = cs->ctx; struct fcgi_conn *fconn = fstrm->fconn; BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); BUG_ON(fstrm->subs && fstrm->subs->events & event_type); - BUG_ON(fstrm->subs && fstrm->subs != sw); + BUG_ON(fstrm->subs && fstrm->subs != es); - sw->events |= event_type; - fstrm->subs = sw; + es->events |= event_type; + fstrm->subs = es; if (event_type & SUB_RETRY_RECV) TRACE_DEVEL("unsubscribe(recv)", FCGI_EV_STRM_RECV, fconn->conn, fstrm); @@ -3725,22 +3723,20 @@ static int fcgi_subscribe(struct conn_stream *cs, int event_type, void *param) return 0; } -/* Called from the upper layer, to unsubscribe some events (undo fcgi_subscribe). - * The argument here is supposed to be a pointer to the same wait_event - * struct that was passed to fcgi_subscribe() otherwise nothing will be changed. - * It always returns zero. +/* Called from the upper layer, to unsubscribe from events + * (undo fcgi_subscribe). The pointer is not allowed to differ from the one + * passed to the subscribe() call. It always returns zero. */ -static int fcgi_unsubscribe(struct conn_stream *cs, int event_type, void *param) +static int fcgi_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct fcgi_strm *fstrm = cs->ctx; struct fcgi_conn *fconn = fstrm->fconn; BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); - BUG_ON(fstrm->subs && fstrm->subs != sw); + BUG_ON(fstrm->subs && fstrm->subs != es); - sw->events &= ~event_type; - if (!sw->events) + es->events &= ~event_type; + if (!es->events) fstrm->subs = NULL; if (event_type & SUB_RETRY_RECV) diff --git a/src/mux_h1.c b/src/mux_h1.c index 6290ae3482..a0adae6ca2 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2542,20 +2542,22 @@ static void h1_shutw_conn(struct connection *conn, enum cs_shw_mode mode) TRACE_LEAVE(H1_EV_STRM_SHUT, conn, h1c->h1s); } -/* Called from the upper layer, to unsubscribe to events */ -static int h1_unsubscribe(struct conn_stream *cs, int event_type, void *param) +/* Called from the upper layer, to unsubscribe from events + * The pointer is not allowed to differ from the one passed to the + * subscribe() call. It always returns zero. + */ +static int h1_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct h1s *h1s = cs->ctx; if (!h1s) return 0; BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); - BUG_ON(h1s->subs && h1s->subs != sw); + BUG_ON(h1s->subs && h1s->subs != es); - sw->events &= ~event_type; - if (!sw->events) + es->events &= ~event_type; + if (!es->events) h1s->subs = NULL; if (event_type & SUB_RETRY_RECV) @@ -2567,10 +2569,14 @@ static int h1_unsubscribe(struct conn_stream *cs, int event_type, void *param) return 0; } -/* 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) +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0, unless + * the conn_stream was already detached, in which case it will return -1. + */ +static int h1_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct h1s *h1s = cs->ctx; struct h1c *h1c; @@ -2579,10 +2585,10 @@ static int h1_subscribe(struct conn_stream *cs, int event_type, void *param) 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); + BUG_ON(h1s->subs && h1s->subs != es); - sw->events |= event_type; - h1s->subs = sw; + es->events |= event_type; + h1s->subs = es; if (event_type & SUB_RETRY_RECV) TRACE_DEVEL("subscribe(recv)", H1_EV_STRM_RECV, h1s->h1c->conn, h1s); diff --git a/src/mux_h2.c b/src/mux_h2.c index 5a1b22672f..d1e93161e0 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -5589,15 +5589,13 @@ static size_t h2s_make_trailers(struct h2s *h2s, struct htx *htx) goto end; } -/* Called from the upper layer, to subscribe to events, such as being able to send. - * The argument here is supposed to be a pointer to a wait_event struct - * which will be passed to h2s->subs. The event_type must only be a - * combination of SUB_RETRY_RECV and SUB_RETRY_SEND, other values will lead to -1 - * being returned. It always returns 0 except for the error above. +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0. */ -static int h2_subscribe(struct conn_stream *cs, int event_type, void *param) +static int h2_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct h2s *h2s = cs->ctx; struct h2c *h2c = h2s->h2c; @@ -5605,10 +5603,10 @@ static int h2_subscribe(struct conn_stream *cs, int event_type, void *param) BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); BUG_ON(h2s->subs && h2s->subs->events & event_type); - BUG_ON(h2s->subs && h2s->subs != sw); + BUG_ON(h2s->subs && h2s->subs != es); - sw->events |= event_type; - h2s->subs = sw; + es->events |= event_type; + h2s->subs = es; if (event_type & SUB_RETRY_RECV) TRACE_DEVEL("subscribe(recv)", H2_EV_STRM_RECV, h2c->conn, h2s); @@ -5627,23 +5625,21 @@ static int h2_subscribe(struct conn_stream *cs, int event_type, void *param) return 0; } -/* Called from the upper layer, to unsubscribe some events (undo h2_subscribe). - * The argument here is supposed to be a pointer to the same wait_event - * struct that was passed to h2_subscribe() otherwise nothing will be changed. - * It always returns zero. +/* Called from the upper layer, to unsubscribe from events . + * The pointer is not allowed to differ from the one passed to the + * subscribe() call. It always returns zero. */ -static int h2_unsubscribe(struct conn_stream *cs, int event_type, void *param) +static int h2_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct h2s *h2s = cs->ctx; TRACE_ENTER(H2_EV_STRM_SEND|H2_EV_STRM_RECV, h2s->h2c->conn, h2s); BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); - BUG_ON(h2s->subs && h2s->subs != sw); + BUG_ON(h2s->subs && h2s->subs != es); - sw->events &= ~event_type; - if (!sw->events) + es->events &= ~event_type; + if (!es->events) h2s->subs = NULL; if (event_type & SUB_RETRY_RECV) diff --git a/src/mux_pt.c b/src/mux_pt.c index ac3711eeb6..4f4ebe9cc8 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -304,15 +304,23 @@ static size_t mux_pt_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t return ret; } -/* Called from the upper layer, to subscribe to events */ -static int mux_pt_subscribe(struct conn_stream *cs, int event_type, void *param) +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0. + */ +static int mux_pt_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - return (cs->conn->xprt->subscribe(cs->conn, cs->conn->xprt_ctx, event_type, param)); + return cs->conn->xprt->subscribe(cs->conn, cs->conn->xprt_ctx, event_type, es); } -static int mux_pt_unsubscribe(struct conn_stream *cs, int event_type, void *param) +/* Called from the upper layer, to unsubscribe from events . + * The pointer is not allowed to differ from the one passed to the + * subscribe() call. It always returns zero. + */ +static int mux_pt_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es) { - return (cs->conn->xprt->unsubscribe(cs->conn, cs->conn->xprt_ctx, event_type, param)); + return cs->conn->xprt->unsubscribe(cs->conn, cs->conn->xprt_ctx, event_type, es); } #if defined(USE_LINUX_SPLICE) diff --git a/src/raw_sock.c b/src/raw_sock.c index 91a3593d97..abd1f5f2e3 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -405,14 +405,23 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s return done; } -static int raw_sock_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0. + */ +static int raw_sock_subscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { - return conn_subscribe(conn, xprt_ctx, event_type, param); + return conn_subscribe(conn, xprt_ctx, event_type, es); } -static int raw_sock_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to unsubscribe from events . + * The pointer is not allowed to differ from the one passed to the + * subscribe() call. It always returns zero. + */ +static int raw_sock_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { - return conn_unsubscribe(conn, xprt_ctx, event_type, param); + return conn_unsubscribe(conn, xprt_ctx, event_type, es); } /* We can't have an underlying XPRT, so just return -1 to signify failure */ diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 783de24d2f..2dcceac0cb 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -6332,9 +6332,14 @@ reneg_ok: return 0; } -static int ssl_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0, + * unless the transport layer was already released. + */ +static int ssl_subscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct ssl_sock_ctx *ctx = xprt_ctx; if (!ctx) @@ -6342,10 +6347,10 @@ static int ssl_subscribe(struct connection *conn, void *xprt_ctx, int event_type BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); BUG_ON(ctx->subs && ctx->subs->events & event_type); - BUG_ON(ctx->subs && ctx->subs != sw); + BUG_ON(ctx->subs && ctx->subs != es); - ctx->subs = sw; - sw->events |= event_type; + ctx->subs = es; + es->events |= event_type; /* we may have to subscribe to lower layers for new events */ event_type &= ~ctx->wait_event.events; @@ -6354,16 +6359,19 @@ static int ssl_subscribe(struct connection *conn, void *xprt_ctx, int event_type return 0; } -static int ssl_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to unsubscribe from events . + * The pointer is not allowed to differ from the one passed to the + * subscribe() call. It always returns zero. + */ +static int ssl_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { struct ssl_sock_ctx *ctx = xprt_ctx; - struct wait_event *sw = param; BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); - BUG_ON(ctx->subs && ctx->subs != sw); + BUG_ON(ctx->subs && ctx->subs != es); - sw->events &= ~event_type; - if (!sw->events) + es->events &= ~event_type; + if (!es->events) ctx->subs = NULL; /* If we subscribed, and we're not doing the handshake, diff --git a/src/xprt_handshake.c b/src/xprt_handshake.c index a175889248..f48d7e8bd9 100644 --- a/src/xprt_handshake.c +++ b/src/xprt_handshake.c @@ -196,31 +196,38 @@ static void xprt_handshake_close(struct connection *conn, void *xprt_ctx) } } -static int xprt_handshake_subscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to subscribe to events . The + * event subscriber is not allowed to change from a previous call as long + * as at least one event is still subscribed. The must only be a + * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0. + */ +static int xprt_handshake_subscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { - struct wait_event *sw = param; struct xprt_handshake_ctx *ctx = xprt_ctx; BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); BUG_ON(ctx->subs && ctx->subs->events & event_type); - BUG_ON(ctx->subs && ctx->subs != sw); + BUG_ON(ctx->subs && ctx->subs != es); - ctx->subs = sw; - sw->events |= event_type; + ctx->subs = es; + es->events |= event_type; return 0; } -static int xprt_handshake_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, void *param) +/* Called from the upper layer, to unsubscribe from events . + * The pointer is not allowed to differ from the one passed to the + * subscribe() call. It always returns zero. + */ +static int xprt_handshake_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es) { struct xprt_handshake_ctx *ctx = xprt_ctx; - struct wait_event *sw = param; BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV)); - BUG_ON(ctx->subs && ctx->subs != sw); + BUG_ON(ctx->subs && ctx->subs != es); - sw->events &= ~event_type; - if (!sw->events) + es->events &= ~event_type; + if (!es->events) ctx->subs = NULL; return 0;