#define EPI_SLAB_DEBUG 0
#endif /* #if DEBUG_EPI != 0 */
+/* Epoll private bits inside the event mask */
+#define EP_PRIVATE_BITS (EPOLLONESHOT | EPOLLET)
/* Maximum number of poll wake up nests we are allowing */
#define EP_MAX_POLLWAKE_NESTS 4
write_lock_irqsave(&ep->lock, flags);
+ /*
+ * If the event mask does not contain any poll(2) event, we consider the
+ * descriptor to be disabled. This condition is likely the effect of the
+ * EPOLLONESHOT bit that disables the descriptor when an event is received,
+ * until the next EPOLL_CTL_MOD will be issued.
+ */
+ if (!(epi->event.events & ~EP_PRIVATE_BITS))
+ goto is_disabled;
+
/* If this file is already in the ready list we exit soon */
if (EP_IS_LINKED(&epi->rdllink))
goto is_linked;
if (waitqueue_active(&ep->poll_wait))
pwake++;
+is_disabled:
write_unlock_irqrestore(&ep->lock, flags);
/* We have to call this outside the lock */
eventcnt += eventbuf;
eventbuf = 0;
}
+ if (epi->event.events & EPOLLONESHOT)
+ epi->event.events &= EP_PRIVATE_BITS;
}
}
#define EPOLL_CTL_DEL 2
#define EPOLL_CTL_MOD 3
+/* Set the One Shot behaviour for the target file descriptor */
+#define EPOLLONESHOT (1 << 30)
+
/* Set the Edge Triggered behaviour for the target file descriptor */
#define EPOLLET (1 << 31)