]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] the epoll FD must not be shared between processes
authorWilly Tarreau <w@1wt.eu>
Sun, 3 Jun 2007 14:40:44 +0000 (16:40 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 3 Jun 2007 14:40:44 +0000 (16:40 +0200)
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.

src/ev_epoll.c
src/ev_sepoll.c

index d313d5690697d1c2396b7613db8e3db81e0a7418..9dccb3526c53271ec0c8f038555dc95e9abeab3f 100644 (file)
@@ -354,6 +354,21 @@ REGPRM1 static int _do_test(struct poller *p)
        return 1;
 }
 
+/*
+ * 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.
@@ -376,6 +391,7 @@ static void _do_register(void)
        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;
index 3e25866f8e246e81af43e23eabbf4a571a11bd12..d304c12900a25916be0b087548b8c6b1736ec2db 100644 (file)
@@ -504,6 +504,21 @@ REGPRM1 static int _do_test(struct poller *p)
        return 1;
 }
 
+/*
+ * 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.
@@ -526,6 +541,7 @@ static void _do_register(void)
        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;