Print this page
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>
@@ -22,11 +22,11 @@
/* All Rights Reserved */
/*
* 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>
#include <sys/sysmacros.h>
#include <sys/param.h>
@@ -8172,15 +8172,11 @@
* Note: POLLRDDATA assumes that synch streams only return messages with
* an M_DATA attached (i.e. not messages consisting of only
* an M_PROTO/M_PCPROTO part).
*/
int
-strpoll(
- struct stdata *stp,
- short events_arg,
- int anyyet,
- short *reventsp,
+strpoll(struct stdata *stp, short events_arg, int anyyet, short *reventsp,
struct pollhead **phpp)
{
int events = (ushort_t)events_arg;
int retevents = 0;
mblk_t *mp;
@@ -8314,12 +8310,11 @@
retevents |= normevents;
else
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.
*/
retevents |= normevents;
}
@@ -8326,23 +8321,15 @@
/* Treat eof as normal data */
if (sd_flags & STREOF)
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) {
*reventsp = POLLNVAL;
return (0);
@@ -8349,10 +8336,12 @@
}
headlocked = 1;
}
stp->sd_rput_opt |= SR_POLLIN;
}
+
+ *reventsp = (short)retevents;
if (headlocked)
mutex_exit(&stp->sd_lock);
return (0);
}