]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: fd: add fd_get_running() to atomically return the running mask
authorWilly Tarreau <w@1wt.eu>
Sat, 9 Jul 2022 12:09:35 +0000 (14:09 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Jul 2022 18:16:30 +0000 (20:16 +0200)
The running mask is only valid if the tgid is the expected one. This
function takes a reference on the tgid before reading the running mask,
so that both are checked at once. It returns either the mask or zero if
the tgid differs, thus providing a simple way for a caller to check if
it still holds the FD.

include/haproxy/fd.h

index 9c085b79a4bf84aa78c63f14c4e77b4abbc1dc94..601419e660f9161e08a65094bb5b3eed439a9b3e 100644 (file)
@@ -387,6 +387,27 @@ static inline void fd_claim_tgid(int fd, uint desired_tgid)
        }
 }
 
+/* atomically read the running mask if the tgid matches, or returns zero if it
+ * does not match. This is meant for use in code paths where the bit is expected
+ * to be present and will be sufficient to protect against a short-term group
+ * migration (e.g. takss and return from iocb).
+ */
+static inline ulong fd_get_running(int fd, uint desired_tgid)
+{
+       ulong ret = 0;
+       uint old;
+
+       /* TODO: may also be checked using an atomic double-load from a DWCAS
+        * on compatible architectures, which wouldn't require to modify nor
+        * restore the original value.
+        */
+       old = _HA_ATOMIC_ADD_FETCH(&fdtab[fd].refc_tgid, 0x10000);
+       if (likely((old & 0xffff) == desired_tgid))
+               ret = _HA_ATOMIC_LOAD(&fdtab[fd].running_mask);
+       _HA_ATOMIC_SUB(&fdtab[fd].refc_tgid, 0x10000);
+       return ret;
+}
+
 /* remove tid_bit from the fd's running mask and returns the bits that remain
  * after the atomic operation.
  */