From 928068a74bf5ab63cd2b459db163ba3199fa36e9 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 19 May 2020 19:14:42 +0200 Subject: [PATCH] MINOR: ring: make the applet code not depend on the CLI The ring to applet communication was only made to deal with CLI functions but it's generic. Let's have generic appctx functions and have the CLI rely on these instead. This patch introduces ring_attach_appctx() and ring_detach_appctx(). --- include/proto/ring.h | 2 ++ src/ring.c | 65 +++++++++++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/include/proto/ring.h b/include/proto/ring.h index a82f93583c..d927b389a7 100644 --- a/include/proto/ring.h +++ b/include/proto/ring.h @@ -30,6 +30,8 @@ struct ring *ring_new(size_t size); struct ring *ring_resize(struct ring *ring, size_t size); void ring_free(struct ring *ring); ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], size_t npfx, const struct ist msg[], size_t nmsg); +int ring_attach_appctx(struct ring *ring, struct appctx *appctx); +void ring_detach_appctx(struct ring *ring, struct appctx *appctx, size_t ofs); int ring_attach_cli(struct ring *ring, struct appctx *appctx); int cli_io_handler_show_ring(struct appctx *appctx); void cli_io_release_show_ring(struct appctx *appctx); diff --git a/src/ring.c b/src/ring.c index 48003b38bc..b6fc4c1dd9 100644 --- a/src/ring.c +++ b/src/ring.c @@ -199,6 +199,44 @@ ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], siz return sent; } +/* Tries to attach appctx as a new reader on ring . This is + * meant to be used by low level appctx code such as CLI or ring forwarding. + * For higher level functions, please see the relevant parts in appctx or CLI. + * It returns non-zero on success or zero on failure if too many users are + * already attached. On success, the caller MUST call ring_detach_appctx() + * to detach itself, even if it was never woken up. + */ +int ring_attach_appctx(struct ring *ring, struct appctx *appctx) +{ + int users = ring->readers_count; + + do { + if (users >= 255) + return 0; + } while (!_HA_ATOMIC_CAS(&ring->readers_count, &users, users + 1)); + return 1; +} + +/* detach an appctx from a ring. The appctx is expected to be waiting at + * offset . Nothing is done if is NULL. + */ +void ring_detach_appctx(struct ring *ring, struct appctx *appctx, size_t ofs) +{ + if (!ring) + return; + + HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock); + if (ofs != ~0) { + /* reader was still attached */ + ofs -= ring->ofs; + BUG_ON(ofs >= b_size(&ring->buf)); + LIST_DEL_INIT(&appctx->wait_entry); + HA_ATOMIC_SUB(b_peek(&ring->buf, ofs), 1); + } + HA_ATOMIC_SUB(&ring->readers_count, 1); + HA_RWLOCK_WRUNLOCK(LOGSRV_LOCK, &ring->lock); +} + /* Tries to attach CLI handler as a new reader on ring . This is * meant to be used when registering a CLI function to dump a buffer, so it * returns zero on success, or non-zero on failure with a message in the appctx @@ -207,15 +245,10 @@ ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], siz */ int ring_attach_cli(struct ring *ring, struct appctx *appctx) { - int users = ring->readers_count; - - do { - if (users >= 255) - return cli_err(appctx, - "Sorry, too many watchers (255) on this ring buffer. " - "What could it have so interesting to attract so many watchers ?"); - - } while (!_HA_ATOMIC_CAS(&ring->readers_count, &users, users + 1)); + if (!ring_attach_appctx(ring, appctx)) + return cli_err(appctx, + "Sorry, too many watchers (255) on this ring buffer. " + "What could it have so interesting to attract so many watchers ?"); if (!appctx->io_handler) appctx->io_handler = cli_io_handler_show_ring; @@ -341,19 +374,7 @@ void cli_io_release_show_ring(struct appctx *appctx) struct ring *ring = appctx->ctx.cli.p0; size_t ofs = appctx->ctx.cli.o0; - if (!ring) - return; - - HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock); - if (ofs != ~0) { - /* reader was still attached */ - ofs -= ring->ofs; - BUG_ON(ofs >= b_size(&ring->buf)); - LIST_DEL_INIT(&appctx->wait_entry); - HA_ATOMIC_SUB(b_peek(&ring->buf, ofs), 1); - } - HA_ATOMIC_SUB(&ring->readers_count, 1); - HA_RWLOCK_WRUNLOCK(LOGSRV_LOCK, &ring->lock); + ring_detach_appctx(ring, appctx, ofs); }