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); }