mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-30 18:13:32 +00:00
MEDIUM: fd: support broadcasting updates for foreign groups in updt_fd_polling
We're still facing the situation where it's impossible to update an FD for a foreign group. That's of particular concern when disabling/enabling listeners (e.g. pause/resume on signals) since we don't decide which thread gets the signal and it needs to process all listeners at once. Fortunately, not that much is unprotected in FDs. This patch adds a test for tgid's equality in updt_fd_polling() so that if a change is applied for a foreing group, then it's detected and taken care of separately. The method consists in forcing the update on all bound threads in this group, adding it to the group's update_list, and sending a wake-up as would be done for a remote thread in the local group, except that this is done by grabbing a reference to the FD's tgid. Thanks to this, SIGTTOU/SIGTTIN now work for nbtgroups > 1 (after that was temporarily broken by "MEDIUM: fd/poller: make the update-list per-group").
This commit is contained in:
parent
1f947cb39e
commit
cfdd20a0b2
30
src/fd.c
30
src/fd.c
@ -466,6 +466,36 @@ int fd_takeover(int fd, void *expected_owner)
|
||||
|
||||
void updt_fd_polling(const int fd)
|
||||
{
|
||||
uint tgrp = fd_take_tgid(fd);
|
||||
|
||||
/* closed ? may happen */
|
||||
if (!tgrp)
|
||||
return;
|
||||
|
||||
if (unlikely(tgrp != tgid && tgrp <= MAX_TGROUPS)) {
|
||||
/* Hmmm delivered an update for another group... That may
|
||||
* happen on suspend/resume of a listener for example when
|
||||
* the FD was not even marked for running. Let's broadcast
|
||||
* the update.
|
||||
*/
|
||||
unsigned long update_mask = fdtab[fd].update_mask;
|
||||
int thr;
|
||||
|
||||
while (!_HA_ATOMIC_CAS(&fdtab[fd].update_mask, &update_mask, ha_tgroup_info[tgrp - 1].threads_enabled))
|
||||
__ha_cpu_relax();
|
||||
|
||||
fd_add_to_fd_list(&update_list[tgrp - 1], fd);
|
||||
|
||||
thr = one_among_mask(fdtab[fd].thread_mask & tg->threads_enabled, statistical_prng_range(MAX_THREADS));
|
||||
thr += ha_tgroup_info[tgrp - 1].base;
|
||||
wake_thread(thr);
|
||||
|
||||
fd_drop_tgid(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
fd_drop_tgid(fd);
|
||||
|
||||
if (tg->threads_enabled == 1UL || (fdtab[fd].thread_mask & tg->threads_enabled) == ti->ltid_bit) {
|
||||
if (HA_ATOMIC_BTS(&fdtab[fd].update_mask, ti->ltid))
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user