diff --git a/usr/src/lib/libc/port/sys/epoll.c b/usr/src/lib/libc/port/sys/epoll.c index 34cb151135bc..e510b0b2473e 100644 --- a/usr/src/lib/libc/port/sys/epoll.c +++ b/usr/src/lib/libc/port/sys/epoll.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2016 Joyent, Inc. + * Copyright 2017 Joyent, Inc. */ #include @@ -64,6 +64,15 @@ #define EPOLLSWIZZLED \ (EPOLLRDHUP | EPOLLONESHOT | EPOLLET | EPOLLWRBAND | EPOLLWRNORM) +/* + * The defined behavior for epoll_wait/epoll_pwait when using a timeout less + * than 0 is to wait for events until they arrive (or interrupted by a signal). + * While poll(7d) operates in this manner for a timeout of -1, using other + * negative values results in an immediate timeout, as if it had been set to 0. + * For that reason, negative values are clamped to -1. + */ +#define EPOLL_TIMEOUT_CLAMP(t) (((t) < -1) ? -1 : (t)) + int epoll_create(int size) { @@ -209,7 +218,7 @@ epoll_wait(int epfd, struct epoll_event *events, } arg.dp_nfds = maxevents; - arg.dp_timeout = timeout; + arg.dp_timeout = EPOLL_TIMEOUT_CLAMP(timeout); arg.dp_fds = (pollfd_t *)events; return (ioctl(epfd, DP_POLL, &arg)); @@ -227,7 +236,7 @@ epoll_pwait(int epfd, struct epoll_event *events, } arg.dp_nfds = maxevents; - arg.dp_timeout = timeout; + arg.dp_timeout = EPOLL_TIMEOUT_CLAMP(timeout); arg.dp_fds = (pollfd_t *)events; arg.dp_setp = (sigset_t *)sigmask; diff --git a/usr/src/uts/common/brand/lx/syscall/lx_epoll.c b/usr/src/uts/common/brand/lx/syscall/lx_epoll.c index f23c1c96a1d8..47688dad6aa8 100644 --- a/usr/src/uts/common/brand/lx/syscall/lx_epoll.c +++ b/usr/src/uts/common/brand/lx/syscall/lx_epoll.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2016 Joyent, Inc. + * Copyright 2017 Joyent, Inc. */ #include @@ -114,6 +114,7 @@ lx_epoll_create(int size) #define EPOLLIGNORED (EPOLLMSG | EPOLLWAKEUP) #define EPOLLSWIZZLED \ (EPOLLRDHUP | EPOLLONESHOT | EPOLLET | EPOLLWRBAND | EPOLLWRNORM) +#define EPOLL_TIMEOUT_CLAMP(t) (((t) < -1) ? -1 : (t)) long lx_epoll_ctl(int fd, int op, int pfd, void *event) @@ -244,7 +245,7 @@ lx_epoll_wait(int fd, void *events, int maxevents, int timeout) } arg.dp_nfds = maxevents; - arg.dp_timeout = timeout; + arg.dp_timeout = EPOLL_TIMEOUT_CLAMP(timeout); arg.dp_fds = (pollfd_t *)events; flag = fp->f_flag | DATAMODEL_NATIVE | FKIOCTL; error = VOP_IOCTL(fp->f_vnode, DP_POLL, (uintptr_t)&arg, flag, @@ -288,7 +289,7 @@ lx_epoll_pwait(int fd, void *events, int maxevents, int timeout, void *sigmask) } arg.dp_nfds = maxevents; - arg.dp_timeout = timeout; + arg.dp_timeout = EPOLL_TIMEOUT_CLAMP(timeout); arg.dp_fds = (pollfd_t *)events; flag = fp->f_flag | DATAMODEL_NATIVE | FKIOCTL; error = VOP_IOCTL(fp->f_vnode, DP_PPOLL, (uintptr_t)&arg, flag,