diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2017-09-22 23:43:19 +0000 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2017-10-18 22:47:16 -0400 |
commit | 80d5689f5d4588adc071138e25e9d0d5252d9b55 (patch) | |
tree | cc01d70fa3d12753675ad425a28ef50a12078dbf /usr/src/uts/common/os/streamio.c | |
parent | ad3ad82ad2fb99c424a8482bd1908d08b990ccea (diff) | |
download | illumos-gate-80d5689f5d4588adc071138e25e9d0d5252d9b55.tar.gz |
8634 epoll fails to wake on certain edge-triggered conditions
8635 epoll should not emit POLLNVAL
8636 recursive epoll should emit EPOLLRDNORM
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/uts/common/os/streamio.c')
-rw-r--r-- | usr/src/uts/common/os/streamio.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c index 62f94729cf..62569eefed 100644 --- a/usr/src/uts/common/os/streamio.c +++ b/usr/src/uts/common/os/streamio.c @@ -24,7 +24,7 @@ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Joyent, Inc. All rights reserved. + * Copyright 2017 Joyent, Inc. */ #include <sys/types.h> @@ -8174,12 +8174,8 @@ out: * an M_PROTO/M_PCPROTO part). */ int -strpoll( - struct stdata *stp, - short events_arg, - int anyyet, - short *reventsp, - struct pollhead **phpp) +strpoll(struct stdata *stp, short events_arg, int anyyet, short *reventsp, + struct pollhead **phpp) { int events = (ushort_t)events_arg; int retevents = 0; @@ -8316,8 +8312,7 @@ chkrd: retevents |= (events & (POLLIN | POLLRDBAND)); break; } - if (! (retevents & normevents) && - (stp->sd_wakeq & RSLEEP)) { + if (!(retevents & normevents) && (stp->sd_wakeq & RSLEEP)) { /* * Sync stream barrier read queue has data. */ @@ -8328,19 +8323,11 @@ chkrd: retevents |= normevents; } - *reventsp = (short)retevents; - if (retevents && !(events & POLLET)) { - if (headlocked) - mutex_exit(&stp->sd_lock); - return (0); - } - /* - * If poll() has not found any events yet, set up event cell - * to wake up the poll if a requested event occurs on this - * stream. Check for collisions with outstanding poll requests. + * Pass back a pollhead if no events are pending or if edge-triggering + * has been configured on this resource. */ - if (!anyyet) { + if ((retevents == 0 && !anyyet) || (events & POLLET)) { *phpp = &stp->sd_pollist; if (headlocked == 0) { if (polllock(&stp->sd_pollist, &stp->sd_lock) != 0) { @@ -8351,6 +8338,8 @@ chkrd: } stp->sd_rput_opt |= SR_POLLIN; } + + *reventsp = (short)retevents; if (headlocked) mutex_exit(&stp->sd_lock); return (0); |