summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2017-01-31 01:33:09 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2017-01-31 19:56:12 +0000
commitd21b3b2e1bbefbd2f6158ed5d329cd58f86677ab (patch)
treeea233e81a5a5b4db239f914348c84776445c55be
parent0e21e957f7ee4ef75f79e71f2fd6f09da211893d (diff)
downloadillumos-joyent-d21b3b2e1bbefbd2f6158ed5d329cd58f86677ab.tar.gz
OS-5926 epoll mishandles excessive timeout negativity
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Ryan Zezeski <ryan.zeseski@joyent.com> Approved by: Ryan Zezeski <ryan.zeseski@joyent.com>
-rw-r--r--usr/src/lib/libc/port/sys/epoll.c15
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_epoll.c7
2 files changed, 16 insertions, 6 deletions
diff --git a/usr/src/lib/libc/port/sys/epoll.c b/usr/src/lib/libc/port/sys/epoll.c
index 34cb151135..e510b0b247 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 <sys/types.h>
@@ -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 f23c1c96a1..47688dad6a 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 <sys/types.h>
@@ -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,