extern volatile struct fdlist update_list;
+extern unsigned long *polled_mask;
+
extern unsigned long fd_cache_mask; // Mask of threads with events in the cache
extern THREAD_LOCAL int *fd_updt; // FD updates list
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 */
struct fdlist_entry cache; /* Entry in the fdcache */
struct fdlist_entry update; /* Entry in the global update list */
REGPRM1 static void __fd_clo(int fd)
{
if (unlikely(fdtab[fd].cloned)) {
- unsigned long m = fdtab[fd].polled_mask;
+ unsigned long m = polled_mask[fd];
int i;
for (i = global.nbthread - 1; i >= 0; i--)
en = fdtab[fd].state;
- if (fdtab[fd].polled_mask & tid_bit) {
+ if (polled_mask[fd] & tid_bit) {
if (!(fdtab[fd].thread_mask & tid_bit) || !(en & FD_EV_POLLED_RW)) {
/* fd removed from poll list */
opcode = EPOLL_CTL_DEL;
- HA_ATOMIC_AND(&fdtab[fd].polled_mask, ~tid_bit);
+ HA_ATOMIC_AND(&polled_mask[fd], ~tid_bit);
}
else {
/* fd status changed */
else if ((fdtab[fd].thread_mask & tid_bit) && (en & FD_EV_POLLED_RW)) {
/* new fd in the poll list */
opcode = EPOLL_CTL_ADD;
- HA_ATOMIC_OR(&fdtab[fd].polled_mask, tid_bit);
+ HA_ATOMIC_OR(&polled_mask[fd], tid_bit);
}
else {
return;
/* FD has been migrated */
activity[tid].poll_skip++;
epoll_ctl(epoll_fd[tid], EPOLL_CTL_DEL, fd, &ev);
- HA_ATOMIC_AND(&fdtab[fd].polled_mask, ~tid_bit);
+ HA_ATOMIC_AND(&polled_mask[fd], ~tid_bit);
continue;
}
en = fdtab[fd].state;
if (!(fdtab[fd].thread_mask & tid_bit) || !(en & FD_EV_POLLED_RW)) {
- if (!(fdtab[fd].polled_mask & tid_bit)) {
+ if (!(polled_mask[fd] & tid_bit)) {
/* fd was not watched, it's still not */
return 0;
}
/* fd totally removed from poll list */
EV_SET(&kev[changes++], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
EV_SET(&kev[changes++], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
- HA_ATOMIC_AND(&fdtab[fd].polled_mask, ~tid_bit);
+ HA_ATOMIC_AND(&polled_mask[fd], ~tid_bit);
}
else {
/* OK fd has to be monitored, it was either added or changed */
if (en & FD_EV_POLLED_R)
EV_SET(&kev[changes++], fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
- else if (fdtab[fd].polled_mask & tid_bit)
+ else if (polled_mask[fd] & tid_bit)
EV_SET(&kev[changes++], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
if (en & FD_EV_POLLED_W)
EV_SET(&kev[changes++], fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
- else if (fdtab[fd].polled_mask & tid_bit)
+ else if (polled_mask[fd] & tid_bit)
EV_SET(&kev[changes++], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
- HA_ATOMIC_OR(&fdtab[fd].polled_mask, tid_bit);
+ HA_ATOMIC_OR(&polled_mask[fd], tid_bit);
}
return changes;
}
* takes it for every other one.
*/
if (!(en & FD_EV_POLLED_RW)) {
- if (!fdtab[fd].polled_mask) {
+ if (!polled_mask[fd]) {
/* fd was not watched, it's still not */
return;
}
/* fd totally removed from poll list */
hap_fd_clr(fd, fd_evts[DIR_RD]);
hap_fd_clr(fd, fd_evts[DIR_WR]);
- HA_ATOMIC_AND(&fdtab[fd].polled_mask, 0);
+ HA_ATOMIC_AND(&polled_mask[fd], 0);
}
else {
/* OK fd has to be monitored, it was either added or changed */
else
hap_fd_set(fd, fd_evts[DIR_WR]);
- HA_ATOMIC_OR(&fdtab[fd].polled_mask, tid_bit);
+ HA_ATOMIC_OR(&polled_mask[fd], tid_bit);
if (fd > *max_add_fd)
*max_add_fd = fd;
}
* takes it for every other one.
*/
if (!(en & FD_EV_POLLED_RW)) {
- if (!fdtab[fd].polled_mask) {
+ if (!polled_mask[fd]) {
/* fd was not watched, it's still not */
return;
}
/* fd totally removed from poll list */
hap_fd_clr(fd, fd_evts[DIR_RD]);
hap_fd_clr(fd, fd_evts[DIR_WR]);
- HA_ATOMIC_AND(&fdtab[fd].polled_mask, 0);
+ HA_ATOMIC_AND(&polled_mask[fd], 0);
}
else {
/* OK fd has to be monitored, it was either added or changed */
else
hap_fd_set(fd, fd_evts[DIR_WR]);
- HA_ATOMIC_OR(&fdtab[fd].polled_mask, tid_bit);
+ HA_ATOMIC_OR(&polled_mask[fd], tid_bit);
if (fd > *max_add_fd)
*max_add_fd = fd;
}
#include <proto/port_range.h>
struct fdtab *fdtab = NULL; /* array of all the file descriptors */
+unsigned long *polled_mask = NULL; /* Array for the polled_mask of each fd */
struct fdinfo *fdinfo = NULL; /* less-often used infos for file descriptors */
int totalconn; /* total # of terminated sessions */
int actconn; /* # of active sessions */
fdtab[fd].update_mask &= ~tid_bit;
fdtab[fd].thread_mask = 0;
if (do_close) {
- fdtab[fd].polled_mask = 0;
+ polled_mask[fd] = 0;
close(fd);
}
HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
if ((fdtab = calloc(global.maxsock, sizeof(struct fdtab))) == NULL)
goto fail_tab;
+ if ((polled_mask = calloc(global.maxsock, sizeof(unsigned long))) == NULL)
+ goto fail_polledmask;
if ((fdinfo = calloc(global.maxsock, sizeof(struct fdinfo))) == NULL)
goto fail_info;
fail_info:
free(fdtab);
fail_tab:
+ free(polled_mask);
+ fail_polledmask:
return 0;
}
free(fdinfo); fdinfo = NULL;
free(fdtab); fdtab = NULL;
+ free(polled_mask); polled_mask = NULL;
}
/*