From 5321da9df086c136731c803cd077bc8005a70c70 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 6 May 2022 11:57:34 +0200 Subject: [PATCH] MEDIUM: lua: move the cosocket storage outside of appctx.ctx The Lua cosockets were using appctx.ctx.hlua_cosocket. Let's move this to a local definition of "hlua_csk_ctx" in hlua.c, which is allocated from the appctx by hlua_socket_new(). There's a notable change which is that, while previously the xref link with the peer was established with the appctx, it's now in the hlua_csk_ctx. This one must then hold a pointer to the appctx. The code was adjusted accordingly, and now that part of the code doesn't use the appctx.ctx anymore. --- include/haproxy/applet-t.h | 7 --- src/hlua.c | 109 ++++++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 46 deletions(-) diff --git a/include/haproxy/applet-t.h b/include/haproxy/applet-t.h index ee77093ade..4cb0f2889f 100644 --- a/include/haproxy/applet-t.h +++ b/include/haproxy/applet-t.h @@ -99,13 +99,6 @@ struct appctx { char storage[APPLET_MAX_SVCCTX]; /* storage of svcctx above */ } svc; /* generic storage for most commands */ union { - struct { - int connected; - struct xref xref; /* cross reference with the Lua object owner. */ - struct list wake_on_read; - struct list wake_on_write; - int die; - } hlua_cosocket; /* used by the Lua cosockets */ struct { struct hlua *hlua; int flags; diff --git a/src/hlua.c b/src/hlua.c index f028d52bab..d630f6d2be 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -242,6 +242,16 @@ struct hlua_flt_ctx { unsigned int flags; /* HLUA_FLT_CTX_FL_* */ }; +/* appctx context used by the cosockets */ +struct hlua_csk_ctx { + int connected; + struct xref xref; /* cross reference with the Lua object owner. */ + struct list wake_on_read; + struct list wake_on_write; + struct appctx *appctx; + int die; +}; + /* used by registered CLI keywords */ struct hlua_cli_ctx { struct hlua *hlua; @@ -1915,24 +1925,25 @@ __LJMP static struct hlua_socket *hlua_checksocket(lua_State *L, int ud) */ static void hlua_socket_handler(struct appctx *appctx) { + struct hlua_csk_ctx *ctx = appctx->svcctx; struct conn_stream *cs = appctx->owner; - if (appctx->ctx.hlua_cosocket.die) { + if (ctx->die) { cs_shutw(cs); cs_shutr(cs); cs_ic(cs)->flags |= CF_READ_NULL; - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&ctx->wake_on_read); + notification_wake(&ctx->wake_on_write); stream_shutdown(__cs_strm(cs), SF_ERR_KILLED); } /* If we can't write, wakeup the pending write signals. */ if (channel_output_closed(cs_ic(cs))) - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&ctx->wake_on_write); /* If we can't read, wakeup the pending read signals. */ if (channel_input_closed(cs_oc(cs))) - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&ctx->wake_on_read); /* if the connection is not established, inform the stream that we want * to be notified whenever the connection completes. @@ -1945,15 +1956,15 @@ static void hlua_socket_handler(struct appctx *appctx) } /* This function is called after the connect. */ - appctx->ctx.hlua_cosocket.connected = 1; + ctx->connected = 1; /* Wake the tasks which wants to write if the buffer have available space. */ if (channel_may_recv(cs_ic(cs))) - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&ctx->wake_on_write); /* Wake the tasks which wants to read if the buffer contains data. */ if (!channel_is_empty(cs_oc(cs))) - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&ctx->wake_on_read); /* Some data were injected in the buffer, notify the stream * interface. @@ -1964,7 +1975,7 @@ static void hlua_socket_handler(struct appctx *appctx) /* If write notifications are registered, we considers we want * to write, so we clear the blocking flag. */ - if (notification_registered(&appctx->ctx.hlua_cosocket.wake_on_write)) + if (notification_registered(&ctx->wake_on_write)) cs_rx_endp_more(cs); } @@ -1974,16 +1985,17 @@ static void hlua_socket_handler(struct appctx *appctx) */ static void hlua_socket_release(struct appctx *appctx) { + struct hlua_csk_ctx *ctx = appctx->svcctx; struct xref *peer; /* Remove my link in the original object. */ - peer = xref_get_peer_and_lock(&appctx->ctx.hlua_cosocket.xref); + peer = xref_get_peer_and_lock(&ctx->xref); if (peer) - xref_disconnect(&appctx->ctx.hlua_cosocket.xref, peer); + xref_disconnect(&ctx->xref, peer); /* Wake all the task waiting for me. */ - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); - notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&ctx->wake_on_read); + notification_wake(&ctx->wake_on_write); } /* If the garbage collectio of the object is launch, nobody @@ -1995,7 +2007,7 @@ static void hlua_socket_release(struct appctx *appctx) __LJMP static int hlua_socket_gc(lua_State *L) { struct hlua_socket *socket; - struct appctx *appctx; + struct hlua_csk_ctx *ctx; struct xref *peer; MAY_LJMP(check_args(L, 1, "__gc")); @@ -2004,11 +2016,12 @@ __LJMP static int hlua_socket_gc(lua_State *L) peer = xref_get_peer_and_lock(&socket->xref); if (!peer) return 0; - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + ctx = container_of(peer, struct hlua_csk_ctx, xref); /* Set the flag which destroy the session. */ - appctx->ctx.hlua_cosocket.die = 1; - appctx_wakeup(appctx); + ctx->die = 1; + appctx_wakeup(ctx->appctx); /* Remove all reference between the Lua stack and the coroutine stream. */ xref_disconnect(&socket->xref, peer); @@ -2021,7 +2034,7 @@ __LJMP static int hlua_socket_gc(lua_State *L) __LJMP static int hlua_socket_close_helper(lua_State *L) { struct hlua_socket *socket; - struct appctx *appctx; + struct hlua_csk_ctx *ctx; struct xref *peer; struct hlua *hlua; @@ -2043,11 +2056,11 @@ __LJMP static int hlua_socket_close_helper(lua_State *L) return 0; hlua->gc_count--; - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + ctx = container_of(peer, struct hlua_csk_ctx, xref); /* Set the flag which destroy the session. */ - appctx->ctx.hlua_cosocket.die = 1; - appctx_wakeup(appctx); + ctx->die = 1; + appctx_wakeup(ctx->appctx); /* Remove all reference between the Lua stack and the coroutine stream. */ xref_disconnect(&socket->xref, peer); @@ -2078,6 +2091,7 @@ __LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1)); int wanted = lua_tointeger(L, 2); struct hlua *hlua; + struct hlua_csk_ctx *csk_ctx; struct appctx *appctx; size_t len; int nblk; @@ -2109,7 +2123,9 @@ __LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua peer = xref_get_peer_and_lock(&socket->xref); if (!peer) goto no_peer; - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + csk_ctx = container_of(peer, struct hlua_csk_ctx, xref); + appctx = csk_ctx->appctx; s = __cs_strm(appctx->owner); oc = &s->res; @@ -2213,7 +2229,7 @@ no_peer: connection_empty: - if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_read, hlua->task)) { + if (!notification_new(&hlua->com, &csk_ctx->wake_on_read, hlua->task)) { xref_unlock(&socket->xref, peer); WILL_LJMP(luaL_error(L, "out of memory")); } @@ -2312,6 +2328,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext { struct hlua_socket *socket; struct hlua *hlua; + struct hlua_csk_ctx *csk_ctx; struct appctx *appctx; size_t buf_len; const char *buf; @@ -2347,7 +2364,9 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext lua_pushinteger(L, -1); return 1; } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + csk_ctx = container_of(peer, struct hlua_csk_ctx, xref); + appctx = csk_ctx->appctx; cs = appctx->owner; s = __cs_strm(cs); @@ -2420,7 +2439,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext } hlua_socket_write_yield_return: - if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) { + if (!notification_new(&hlua->com, &csk_ctx->wake_on_write, hlua->task)) { xref_unlock(&socket->xref, peer); WILL_LJMP(luaL_error(L, "out of memory")); } @@ -2580,7 +2599,8 @@ __LJMP static int hlua_socket_getpeername(struct lua_State *L) lua_pushnil(L); return 1; } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + appctx = container_of(peer, struct hlua_csk_ctx, xref)->appctx; cs = appctx->owner; dst = cs_dst(cs_opposite(cs)); if (!dst) { @@ -2620,7 +2640,8 @@ static int hlua_socket_getsockname(struct lua_State *L) lua_pushnil(L); return 1; } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + appctx = container_of(peer, struct hlua_csk_ctx, xref)->appctx; s = __cs_strm(appctx->owner); conn = cs_conn(s->csb); @@ -2648,6 +2669,7 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1)); struct hlua *hlua; struct xref *peer; + struct hlua_csk_ctx *csk_ctx; struct appctx *appctx; struct stream *s; @@ -2669,7 +2691,9 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua lua_pushstring(L, "Can't connect"); return 2; } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + csk_ctx = container_of(peer, struct hlua_csk_ctx, xref); + appctx = csk_ctx->appctx; s = __cs_strm(appctx->owner); /* Check if we run on the same thread than the xreator thread. @@ -2691,13 +2715,13 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua appctx = __cs_appctx(s->csf); /* Check for connection established. */ - if (appctx->ctx.hlua_cosocket.connected) { + if (csk_ctx->connected) { xref_unlock(&socket->xref, peer); lua_pushinteger(L, 1); return 1; } - if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) { + if (!notification_new(&hlua->com, &csk_ctx->wake_on_write, hlua->task)) { xref_unlock(&socket->xref, peer); WILL_LJMP(luaL_error(L, "out of memory error")); } @@ -2713,6 +2737,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L) int port = -1; const char *ip; struct hlua *hlua; + struct hlua_csk_ctx *csk_ctx; struct appctx *appctx; int low, high; struct sockaddr_storage *addr; @@ -2780,7 +2805,8 @@ __LJMP static int hlua_socket_connect(struct lua_State *L) } } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + csk_ctx = container_of(peer, struct hlua_csk_ctx, xref); + appctx = csk_ctx->appctx; cs = appctx->owner; s = __cs_strm(cs); @@ -2803,7 +2829,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L) hlua->gc_count++; - if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) { + if (!notification_new(&hlua->com, &csk_ctx->wake_on_write, hlua->task)) { xref_unlock(&socket->xref, peer); WILL_LJMP(luaL_error(L, "out of memory")); } @@ -2834,7 +2860,8 @@ __LJMP static int hlua_socket_connect_ssl(struct lua_State *L) lua_pushnil(L); return 1; } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + appctx = container_of(peer, struct hlua_csk_ctx, xref)->appctx; s = __cs_strm(appctx->owner); s->target = &socket_ssl->obj_type; @@ -2888,7 +2915,8 @@ __LJMP static int hlua_socket_settimeout(struct lua_State *L) WILL_LJMP(lua_error(L)); return 0; } - appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref); + + appctx = container_of(peer, struct hlua_csk_ctx, xref)->appctx; s = __cs_strm(appctx->owner); s->sess->fe->timeout.connect = tmout; @@ -2913,6 +2941,7 @@ __LJMP static int hlua_socket_settimeout(struct lua_State *L) __LJMP static int hlua_socket_new(lua_State *L) { struct hlua_socket *socket; + struct hlua_csk_ctx *ctx; struct appctx *appctx; struct session *sess; struct conn_stream *cs; @@ -2948,10 +2977,12 @@ __LJMP static int hlua_socket_new(lua_State *L) goto out_fail_conf; } - appctx->ctx.hlua_cosocket.connected = 0; - appctx->ctx.hlua_cosocket.die = 0; - LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_write); - LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_read); + ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); + ctx->connected = 0; + ctx->appctx = appctx; + ctx->die = 0; + LIST_INIT(&ctx->wake_on_write); + LIST_INIT(&ctx->wake_on_read); /* Now create a session, task and stream for this applet */ sess = session_new(socket_proxy, NULL, &appctx->obj_type); @@ -2969,7 +3000,7 @@ __LJMP static int hlua_socket_new(lua_State *L) s = DISGUISE(cs_strm(cs)); /* Initialise cross reference between stream and Lua socket object. */ - xref_create(&socket->xref, &appctx->ctx.hlua_cosocket.xref); + xref_create(&socket->xref, &ctx->xref); /* Configure "right" conn-stream. this "si" is used to connect * and retrieve data from the server. The connection is initialized -- 2.47.3