]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ring: make the applet code not depend on the CLI
authorWilly Tarreau <w@1wt.eu>
Tue, 19 May 2020 17:14:42 +0000 (19:14 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 19 May 2020 17:37:12 +0000 (19:37 +0200)
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
src/ring.c

index a82f93583cff317b9faae56877bfcdf88cd7da8f..d927b389a7f313b1d36cfd10db6e3a3df9d4ee79 100644 (file)
@@ -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);
index 48003b38bc01d2b28e496a83e977cec34dd55bbf..b6fc4c1dd9748c5ba3d97c0ac1984cd0c5a36512 100644 (file)
@@ -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 <appctx> as a new reader on ring <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 <ofs>. Nothing is done if <ring> 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 <appctx> as a new reader on ring <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);
 }