Getting pollers such as select and poll to work when thread groups
unshared their file descriptors would require to have per-thread groups
arrays of file descriptors. Given making each thread group its own file
descriptor table is done for performance reasons, and those pollers will
never perform very well, this does not seem to be worth it.
kqueue and evports would work, except that they are only implemented on
OSes that do not provide the equivalent of the unshare() system call.
So effectively, only epoll can be used as a poller when fds are not
shared across thread groups.
#define HAP_POLL_F_RDHUP 0x00000001 /* the poller notifies of HUP with reads */
#define HAP_POLL_F_ERRHUP 0x00000002 /* the poller reports ERR and HUP */
+#define HAP_POLL_F_NO_FD_SHARING 0x00000004 /* the poller supports not sharing fds across thread groups */
struct poller {
void *private; /* any private data for the poller */
p->name = "epoll";
p->pref = 300;
- p->flags = HAP_POLL_F_ERRHUP; // note: RDHUP might be dynamically added
+ p->flags = HAP_POLL_F_ERRHUP | HAP_POLL_F_NO_FD_SHARING; // note: RDHUP might be dynamically added
p->private = NULL;
p->clo = __fd_clo;
do {
bp = NULL;
+redo:
for (p = 0; p < nbpollers; p++)
if (!bp || (pollers[p].pref > bp->pref))
bp = &pollers[p];
if (!bp || bp->pref == 0)
break;
+ if ((global.tune.options & GTUNE_NO_TG_FD_SHARING) &&
+ !(bp->flags & HAP_POLL_F_NO_FD_SHARING)) {
+ ha_alert("Can't use poller '%s' with per-thread-group FD tables\n", bp->name);
+ bp->pref = 0;
+ goto redo;
+ }
+
if (bp->init(bp)) {
memcpy(&cur_poller, bp, sizeof(*bp));
return 1;