zos: reset epoll data after fork

Remove all the epoll file descriptors after a fork since they are
no longer valid. The uv__signal_global_once_init function needs to
be run after uv__platform_loop_init so that the epoll pthread_atfork
handlers get run first.

PR-URL: https://github.com/libuv/libuv/pull/1496
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
John Barboza 2017-08-21 00:45:19 -04:00 committed by Santiago Gimeno
parent 6a101e78e8
commit 44b7c71035
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
2 changed files with 32 additions and 1 deletions

View File

@ -31,7 +31,6 @@ int uv_loop_init(uv_loop_t* loop) {
void* saved_data;
int err;
uv__signal_global_once_init();
saved_data = loop->data;
memset(loop, 0, sizeof(*loop));
@ -68,6 +67,7 @@ int uv_loop_init(uv_loop_t* loop) {
if (err)
return err;
uv__signal_global_once_init();
err = uv_signal_init(loop, &loop->child_watcher);
if (err)
goto fail_signal_init;

View File

@ -120,10 +120,41 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) {
}
static void before_fork(void) {
uv_mutex_lock(&global_epoll_lock);
}
static void after_fork(void) {
uv_mutex_unlock(&global_epoll_lock);
}
static void child_fork(void) {
QUEUE* q;
uv_once_t child_once = UV_ONCE_INIT;
/* reset once */
memcpy(&once, &child_once, sizeof(child_once));
/* reset epoll list */
while (!QUEUE_EMPTY(&global_epoll_queue)) {
q = QUEUE_HEAD(&global_epoll_queue);
QUEUE_REMOVE(q);
}
uv_mutex_unlock(&global_epoll_lock);
uv_mutex_destroy(&global_epoll_lock);
}
static void epoll_init(void) {
QUEUE_INIT(&global_epoll_queue);
if (uv_mutex_init(&global_epoll_lock))
abort();
if (pthread_atfork(&before_fork, &after_fork, &child_fork))
abort();
}