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,32 ****
/* All Rights Reserved */
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/param.h>
--- 22,32 ----
/* All Rights Reserved */
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2017 Joyent, Inc.
*/
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/param.h>
*** 8172,8186 ****
* 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,
struct pollhead **phpp)
{
int events = (ushort_t)events_arg;
int retevents = 0;
mblk_t *mp;
--- 8172,8182 ----
* 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,
struct pollhead **phpp)
{
int events = (ushort_t)events_arg;
int retevents = 0;
mblk_t *mp;
*** 8314,8325 ****
retevents |= normevents;
else
retevents |= (events & (POLLIN | POLLRDBAND));
break;
}
! if (! (retevents & normevents) &&
! (stp->sd_wakeq & RSLEEP)) {
/*
* Sync stream barrier read queue has data.
*/
retevents |= normevents;
}
--- 8310,8320 ----
retevents |= normevents;
else
retevents |= (events & (POLLIN | POLLRDBAND));
break;
}
! if (!(retevents & normevents) && (stp->sd_wakeq & RSLEEP)) {
/*
* Sync stream barrier read queue has data.
*/
retevents |= normevents;
}
*** 8326,8348 ****
/* 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.
*/
! if (!anyyet) {
*phpp = &stp->sd_pollist;
if (headlocked == 0) {
if (polllock(&stp->sd_pollist, &stp->sd_lock) != 0) {
*reventsp = POLLNVAL;
return (0);
--- 8321,8335 ----
/* Treat eof as normal data */
if (sd_flags & STREOF)
retevents |= normevents;
}
/*
! * Pass back a pollhead if no events are pending or if edge-triggering
! * has been configured on this resource.
*/
! 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,8358 ****
--- 8336,8347 ----
}
headlocked = 1;
}
stp->sd_rput_opt |= SR_POLLIN;
}
+
+ *reventsp = (short)retevents;
if (headlocked)
mutex_exit(&stp->sd_lock);
return (0);
}