Skip to content

Commit

Permalink
OS-5926 epoll mishandles excessive timeout negativity
Browse files Browse the repository at this point in the history
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Ryan Zezeski <ryan.zeseski@joyent.com>
Approved by: Ryan Zezeski <ryan.zeseski@joyent.com>
  • Loading branch information
pfmooney committed Jan 31, 2017
1 parent 0e21e95 commit d21b3b2
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
15 changes: 12 additions & 3 deletions usr/src/lib/libc/port/sys/epoll.c
Expand Up @@ -10,7 +10,7 @@
*/

/*
* Copyright 2016 Joyent, Inc.
* Copyright 2017 Joyent, Inc.
*/

#include <sys/types.h>
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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));
Expand All @@ -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;

Expand Down
7 changes: 4 additions & 3 deletions usr/src/uts/common/brand/lx/syscall/lx_epoll.c
Expand Up @@ -10,7 +10,7 @@
*/

/*
* Copyright 2016 Joyent, Inc.
* Copyright 2017 Joyent, Inc.
*/

#include <sys/types.h>
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit d21b3b2

Please sign in to comment.