mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02: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
@ -354,6 +354,21 @@ REGPRM1 static int _do_test(struct poller *p)
|
|||||||
return 1;
|
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
|
* 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.
|
* 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->init = _do_init;
|
||||||
p->term = _do_term;
|
p->term = _do_term;
|
||||||
p->poll = _do_poll;
|
p->poll = _do_poll;
|
||||||
|
p->fork = _do_fork;
|
||||||
|
|
||||||
p->is_set = __fd_is_set;
|
p->is_set = __fd_is_set;
|
||||||
p->cond_s = p->set = __fd_set;
|
p->cond_s = p->set = __fd_set;
|
||||||
|
@ -504,6 +504,21 @@ REGPRM1 static int _do_test(struct poller *p)
|
|||||||
return 1;
|
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
|
* 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.
|
* 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->init = _do_init;
|
||||||
p->term = _do_term;
|
p->term = _do_term;
|
||||||
p->poll = _do_poll;
|
p->poll = _do_poll;
|
||||||
|
p->fork = _do_fork;
|
||||||
|
|
||||||
p->is_set = __fd_is_set;
|
p->is_set = __fd_is_set;
|
||||||
p->cond_s = p->set = __fd_set;
|
p->cond_s = p->set = __fd_set;
|
||||||
|
Loading…
Reference in New Issue
Block a user