#define FD_CLONED_BIT 17 /* cloned socket, requires EPOLL_CTL_DEL on close */
#define FD_INITIALIZED_BIT 18 /* init phase was done (e.g. output pipe set non-blocking) */
#define FD_ET_POSSIBLE_BIT 19 /* edge-triggered is possible on this FD */
+#define FD_EXPORTED_BIT 20 /* FD is exported and must not be closed */
/* and flag values */
#define FD_CLONED (1U << FD_CLONED_BIT)
#define FD_INITIALIZED (1U << FD_INITIALIZED_BIT)
#define FD_ET_POSSIBLE (1U << FD_ET_POSSIBLE_BIT)
+#define FD_EXPORTED (1U << FD_EXPORTED_BIT)
/* This is the value used to mark a file descriptor as dead. This value is
* negative, this is important so that tests on fd < 0 properly match. It
void (*iocb)(int fd); /* I/O handler */
void *owner; /* the connection or listener associated with this fd, NULL if closed */
unsigned int state; /* FD state for read and write directions (FD_EV_*) + FD_POLL_* */
- unsigned char exported:1; /* 1 if the FD is exported and must not be closed */
#ifdef DEBUG_FD
unsigned int event_count; /* number of events reported */
#endif
fdtab[fd].owner = owner;
fdtab[fd].iocb = iocb;
fdtab[fd].state = 0;
- fdtab[fd].exported = 0;
#ifdef DEBUG_FD
fdtab[fd].event_count = 0;
#endif
* the caller know how much it should expect.
*/
for (cur_fd = 0;cur_fd < global.maxsock; cur_fd++)
- tot_fd_nb += fdtab[cur_fd].exported;
+ tot_fd_nb += !!(fdtab[cur_fd].state & FD_EXPORTED);
if (tot_fd_nb == 0)
goto out;
nb_queued = 0;
iov.iov_base = tmpbuf;
for (cur_fd = 0; cur_fd < global.maxsock; cur_fd++) {
- if (!(fdtab[cur_fd].exported))
+ if (!(fdtab[cur_fd].state & FD_EXPORTED))
continue;
ns_name = if_name = "";
#endif
fdinfo[fd].port_range = NULL;
fdtab[fd].owner = NULL;
- fdtab[fd].exported = 0;
/* perform the close() call last as it's what unlocks the instant reuse
* of this FD by any other thread.
*/
/* for now, all regularly bound TCP listeners are exportable */
if (!(rx->flags & RX_F_INHERITED))
- fdtab[fd].exported = 1;
+ HA_ATOMIC_OR(&fdtab[fd].state, FD_EXPORTED);
bind_return:
if (errmsg && *errmsg) {
/* for now, all regularly bound TCP listeners are exportable */
if (!(rx->flags & RX_F_INHERITED))
- fdtab[fd].exported = 1;
+ HA_ATOMIC_OR(&fdtab[fd].state, FD_EXPORTED);
return err;