zos: lock protect global epoll list in epoll_ctl

This will eliminate a race condition that occurs between
epoll_close_fd, epoll_ctl and epoll_create in the
signal_multiple_loops test.

PR-URL: https://github.com/libuv/libuv/pull/1560
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
John Barboza 2017-09-23 11:57:45 -04:00 committed by Ben Noordhuis
parent b21c1f900c
commit 24334e0739
2 changed files with 16 additions and 10 deletions

View File

@ -130,17 +130,17 @@ static void epoll_init(void) {
uv__os390_epoll* epoll_create1(int flags) {
uv__os390_epoll* lst;
uv_once(&once, epoll_init);
uv_mutex_lock(&global_epoll_lock);
lst = uv__malloc(sizeof(*lst));
if (lst == -1)
return NULL;
QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
uv_mutex_unlock(&global_epoll_lock);
if (lst != NULL) {
/* initialize list */
lst->size = 0;
lst->items = NULL;
uv_once(&once, epoll_init);
uv_mutex_lock(&global_epoll_lock);
QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
uv_mutex_unlock(&global_epoll_lock);
}
/* initialize list */
lst->size = 0;
lst->items = NULL;
return lst;
}
@ -149,8 +149,11 @@ int epoll_ctl(uv__os390_epoll* lst,
int op,
int fd,
struct epoll_event *event) {
uv_mutex_lock(&global_epoll_lock);
if(op == EPOLL_CTL_DEL) {
if (fd >= lst->size || lst->items[fd].fd == -1) {
uv_mutex_unlock(&global_epoll_lock);
errno = ENOENT;
return -1;
}
@ -158,6 +161,7 @@ int epoll_ctl(uv__os390_epoll* lst,
} else if(op == EPOLL_CTL_ADD) {
maybe_resize(lst, fd + 1);
if (lst->items[fd].fd != -1) {
uv_mutex_unlock(&global_epoll_lock);
errno = EEXIST;
return -1;
}
@ -165,6 +169,7 @@ int epoll_ctl(uv__os390_epoll* lst,
lst->items[fd].events = event->events;
} else if(op == EPOLL_CTL_MOD) {
if (fd >= lst->size || lst->items[fd].fd == -1) {
uv_mutex_unlock(&global_epoll_lock);
errno = ENOENT;
return -1;
}
@ -172,6 +177,7 @@ int epoll_ctl(uv__os390_epoll* lst,
} else
abort();
uv_mutex_unlock(&global_epoll_lock);
return 0;
}

View File

@ -117,7 +117,7 @@ void uv_loadavg(double avg[3]) {
int uv__platform_loop_init(uv_loop_t* loop) {
uv__os390_epoll* ep;
ep = epoll_create1(UV__EPOLL_CLOEXEC);
ep = epoll_create1(0);
loop->ep = ep;
if (ep == NULL)
return -errno;