updt_fd_polling(fd);
}
-/* Update events seen for FD <fd> and its state if needed. This should be called
- * by the poller to set FD_POLL_* flags. */
-static inline void fd_update_events(int fd, int evts)
+/* Update events seen for FD <fd> and its state if needed. This should be
+ * called by the poller, passing FD_EV_*_{R,W,RW} in <evts>. FD_EV_ERR_*
+ * doesn't need to also pass FD_EV_SHUT_*, it's implied. ERR and SHUT are
+ * allowed to be reported regardless of R/W readiness.
+ */
+static inline void fd_update_events(int fd, unsigned char evts)
{
unsigned long locked = atleast2(fdtab[fd].thread_mask);
unsigned char old, new;
+ int new_flags;
+
+ new_flags =
+ ((evts & FD_EV_READY_R) ? FD_POLL_IN : 0) |
+ ((evts & FD_EV_READY_W) ? FD_POLL_OUT : 0) |
+ ((evts & FD_EV_SHUT_R) ? FD_POLL_HUP : 0) |
+ ((evts & FD_EV_SHUT_W) ? FD_POLL_ERR : 0) |
+ ((evts & FD_EV_ERR_R) ? FD_POLL_ERR : 0) |
+ ((evts & FD_EV_ERR_W) ? FD_POLL_ERR : 0);
old = fdtab[fd].ev;
- new = (old & FD_POLL_STICKY) | evts;
+ new = (old & FD_POLL_STICKY) | new_flags;
if (unlikely(locked)) {
/* Locked FDs (those with more than 2 threads) are atomically updated */
while (unlikely(new != old && !_HA_ATOMIC_CAS(&fdtab[fd].ev, &old, new)))
- new = (old & FD_POLL_STICKY) | evts;
+ new = (old & FD_POLL_STICKY) | new_flags;
} else {
if (new != old)
fdtab[fd].ev = new;
continue;
}
- /* it looks complicated but gcc can optimize it away when constants
- * have same values... In fact it depends on gcc :-(
- */
- if (EPOLLIN == FD_POLL_IN && EPOLLOUT == FD_POLL_OUT &&
- EPOLLPRI == FD_POLL_PRI && EPOLLERR == FD_POLL_ERR &&
- EPOLLHUP == FD_POLL_HUP) {
- n = e & (EPOLLIN|EPOLLOUT|EPOLLPRI|EPOLLERR|EPOLLHUP);
- }
- else {
- n = ((e & EPOLLIN ) ? FD_POLL_IN : 0) |
- ((e & EPOLLPRI) ? FD_POLL_PRI : 0) |
- ((e & EPOLLOUT) ? FD_POLL_OUT : 0) |
- ((e & EPOLLERR) ? FD_POLL_ERR : 0) |
- ((e & EPOLLHUP) ? FD_POLL_HUP : 0);
- }
+ n = ((e & EPOLLIN) ? FD_EV_READY_R : 0) |
+ ((e & EPOLLOUT) ? FD_EV_READY_W : 0) |
+ ((e & EPOLLRDHUP) ? FD_EV_SHUT_R : 0) |
+ ((e & EPOLLHUP) ? FD_EV_SHUT_RW : 0) |
+ ((e & EPOLLERR) ? FD_EV_ERR_RW : 0);
- /* always remap RDHUP to HUP as they're used similarly */
- if (e & EPOLLRDHUP) {
+ if ((e & EPOLLRDHUP) && !(cur_poller.flags & HAP_POLL_F_RDHUP))
_HA_ATOMIC_OR(&cur_poller.flags, HAP_POLL_F_RDHUP);
- n |= FD_POLL_HUP;
- }
+
fd_update_events(fd, n);
}
/* the caller will take care of cached events */
/*
* Set bits based on the events we received from the port:
*/
- if (events & POLLIN)
- n |= FD_POLL_IN;
- if (events & POLLOUT)
- n |= FD_POLL_OUT;
- if (events & POLLERR)
- n |= FD_POLL_ERR;
- if (events & POLLHUP)
- n |= FD_POLL_HUP;
+ n = ((e & POLLIN) ? FD_EV_READY_R : 0) |
+ ((e & POLLOUT) ? FD_EV_READY_W : 0) |
+ ((e & POLLHUP) ? FD_EV_SHUT_RW : 0) |
+ ((e & POLLERR) ? FD_EV_ERR_RW : 0);
/*
* Call connection processing callbacks. Note that it's
continue;
}
- if (kev[count].filter == EVFILT_READ) {
+ if (kev[count].filter == EVFILT_READ) {
if (kev[count].data)
- n |= FD_POLL_IN;
+ n |= FD_EV_READY_R;
if (kev[count].flags & EV_EOF)
- n |= FD_POLL_HUP;
+ n |= FD_EV_SHUT_R;
}
- else if (kev[count].filter == EVFILT_WRITE) {
- n |= FD_POLL_OUT;
+ else if (kev[count].filter == EVFILT_WRITE) {
+ n |= FD_EV_READY_W;
if (kev[count].flags & EV_EOF)
- n |= FD_POLL_ERR;
+ n |= FD_EV_ERR_RW;
}
fd_update_events(fd, n);
continue;
}
- /* it looks complicated but gcc can optimize it away when constants
- * have same values... In fact it depends on gcc :-(
- */
- if (POLLIN == FD_POLL_IN && POLLOUT == FD_POLL_OUT &&
- POLLERR == FD_POLL_ERR && POLLHUP == FD_POLL_HUP) {
- n = e & (POLLIN|POLLOUT|POLLERR|POLLHUP);
- }
- else {
- n = ((e & POLLIN ) ? FD_POLL_IN : 0) |
- ((e & POLLOUT) ? FD_POLL_OUT : 0) |
- ((e & POLLERR) ? FD_POLL_ERR : 0) |
- ((e & POLLHUP) ? FD_POLL_HUP : 0);
- }
+ n = ((e & POLLIN) ? FD_EV_READY_R : 0) |
+ ((e & POLLOUT) ? FD_EV_READY_W : 0) |
+ ((e & POLLRDHUP) ? FD_EV_SHUT_R : 0) |
+ ((e & POLLHUP) ? FD_EV_SHUT_RW : 0) |
+ ((e & POLLERR) ? FD_EV_ERR_RW : 0);
- /* always remap RDHUP to HUP as they're used similarly */
- if (e & POLLRDHUP) {
+ if ((e & POLLRDHUP) && !(cur_poller.flags & HAP_POLL_F_RDHUP))
_HA_ATOMIC_OR(&cur_poller.flags, HAP_POLL_F_RDHUP);
- n |= FD_POLL_HUP;
- }
+
fd_update_events(fd, n);
}
}
if (FD_ISSET(fd, tmp_evts[DIR_RD]))
- n |= FD_POLL_IN;
+ n |= FD_EV_READY_R;
if (FD_ISSET(fd, tmp_evts[DIR_WR]))
- n |= FD_POLL_OUT;
+ n |= FD_EV_READY_W;
fd_update_events(fd, n);
}