[BUG] the epoll FD must not be shared between processes
Recreate the epoll file descriptor after a fork(). It will ensure
that all processes will not share their epoll_fd. Some side effects
were encountered because of this, such as epoll_wait() returning an
FD which was previously deleted, in multi-process mode.
diff --git a/src/ev_epoll.c b/src/ev_epoll.c
index d313d56..9dccb35 100644
--- a/src/ev_epoll.c
+++ b/src/ev_epoll.c
@@ -355,6 +355,21 @@
}
/*
+ * Recreate the epoll file descriptor after a fork(). Returns 1 if OK,
+ * otherwise 0. It will ensure that all processes will not share their
+ * epoll_fd. Some side effects were encountered because of this, such
+ * as epoll_wait() returning an FD which was previously deleted.
+ */
+REGPRM1 static int _do_fork(struct poller *p)
+{
+ close(epoll_fd);
+ epoll_fd = epoll_create(global.maxsock + 1);
+ if (epoll_fd < 0)
+ return 0;
+ return 1;
+}
+
+/*
* It is a constructor, which means that it will automatically be called before
* main(). This is GCC-specific but it works at least since 2.95.
* Special care must be taken so that it does not need any uninitialized data.
@@ -376,6 +391,7 @@
p->init = _do_init;
p->term = _do_term;
p->poll = _do_poll;
+ p->fork = _do_fork;
p->is_set = __fd_is_set;
p->cond_s = p->set = __fd_set;
diff --git a/src/ev_sepoll.c b/src/ev_sepoll.c
index 3e25866..d304c12 100644
--- a/src/ev_sepoll.c
+++ b/src/ev_sepoll.c
@@ -505,6 +505,21 @@
}
/*
+ * Recreate the epoll file descriptor after a fork(). Returns 1 if OK,
+ * otherwise 0. It will ensure that all processes will not share their
+ * epoll_fd. Some side effects were encountered because of this, such
+ * as epoll_wait() returning an FD which was previously deleted.
+ */
+REGPRM1 static int _do_fork(struct poller *p)
+{
+ close(epoll_fd);
+ epoll_fd = epoll_create(global.maxsock + 1);
+ if (epoll_fd < 0)
+ return 0;
+ return 1;
+}
+
+/*
* It is a constructor, which means that it will automatically be called before
* main(). This is GCC-specific but it works at least since 2.95.
* Special care must be taken so that it does not need any uninitialized data.
@@ -526,6 +541,7 @@
p->init = _do_init;
p->term = _do_term;
p->poll = _do_poll;
+ p->fork = _do_fork;
p->is_set = __fd_is_set;
p->cond_s = p->set = __fd_set;