mirror of
https://github.com/haproxy/haproxy.git
synced 2026-06-03 22:02:52 -04:00
[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.
This commit is contained in:
parent
ab3e1d313c
commit
fb8983f21b
2 changed files with 32 additions and 0 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue