summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/tevent/tevent_epoll.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 3608d4b622..3e3ddf9d3f 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -587,6 +587,38 @@ static void epoll_update_event(struct epoll_event_context *epoll_ev, struct teve
}
/*
+ Cope with epoll returning EPOLLHUP|EPOLLERR on an event.
+ Return true if there's nothing else to do, false if
+ this event needs further handling.
+*/
+static bool epoll_handle_hup_or_err(struct epoll_event_context *epoll_ev,
+ struct tevent_fd *fde)
+{
+ if (fde == NULL) {
+ /* Nothing to do if no event. */
+ return true;
+ }
+
+ fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
+ /*
+ * if we only wait for TEVENT_FD_WRITE, we should not tell the
+ * event handler about it, and remove the epoll_event,
+ * as we only report errors when waiting for read events,
+ * to match the select() behavior
+ */
+ if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
+ /*
+ * Do the same as the poll backend and
+ * remove the writeable flag.
+ */
+ fde->flags &= ~TEVENT_FD_WRITE;
+ return true;
+ }
+ /* This has TEVENT_FD_READ set, we're not finished. */
+ return false;
+}
+
+/*
event loop handling using epoll
*/
static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp)