MINOR: fd: add fd_get_running() to atomically return the running mask

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.
This commit is contained in:
Willy Tarreau 2022-07-09 14:09:35 +02:00
parent 080373ea38
commit ceffd17f52

View 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.
*/