diff --git a/include/proto/fd.h b/include/proto/fd.h index d6b591d19..cc559ac32 100644 --- a/include/proto/fd.h +++ b/include/proto/fd.h @@ -405,6 +405,9 @@ static inline void fd_insert(int fd, unsigned long thread_mask) fdtab[fd].cloned = 0; fdtab[fd].cache = 0; fdtab[fd].thread_mask = thread_mask; + /* note: do not reset polled_mask here as it indicates which poller + * still knows this FD from a possible previous round. + */ HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock); HA_SPIN_LOCK(FDTAB_LOCK, &fdtab_lock); diff --git a/include/types/fd.h b/include/types/fd.h index 54192e478..9f2c5feea 100644 --- a/include/types/fd.h +++ b/include/types/fd.h @@ -94,6 +94,7 @@ enum fd_states { struct fdtab { __decl_hathreads(HA_SPINLOCK_T lock); unsigned long thread_mask; /* mask of thread IDs authorized to process the task */ + unsigned long polled_mask; /* mask of thread IDs currently polling this fd */ unsigned long update_mask; /* mask of thread IDs having an update for fd */ void (*iocb)(int fd); /* I/O handler */ void *owner; /* the connection or listener associated with this fd, NULL if closed */ diff --git a/src/fd.c b/src/fd.c index 112806bbb..b64130ed0 100644 --- a/src/fd.c +++ b/src/fd.c @@ -202,8 +202,10 @@ static void fd_dodelete(int fd, int do_close) fdtab[fd].update_mask &= ~tid_bit; fdtab[fd].new = 0; fdtab[fd].thread_mask = 0; - if (do_close) + if (do_close) { + fdtab[fd].polled_mask = 0; close(fd); + } HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock); HA_SPIN_LOCK(FDTAB_LOCK, &fdtab_lock);