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>
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * Support for the eventfd facility, a Linux-borne facility for user-generated
  18  * file descriptor-based events.
  19  */
  20 
  21 #include <sys/ddi.h>
  22 #include <sys/sunddi.h>
  23 #include <sys/eventfd.h>
  24 #include <sys/conf.h>
  25 #include <sys/vmem.h>
  26 #include <sys/sysmacros.h>
  27 #include <sys/filio.h>
  28 #include <sys/stat.h>
  29 #include <sys/file.h>
  30 
  31 struct eventfd_state;
  32 typedef struct eventfd_state eventfd_state_t;
  33 


 211 
 212 /*ARGSUSED*/
 213 static int
 214 eventfd_poll(dev_t dev, short events, int anyyet, short *reventsp,
 215     struct pollhead **phpp)
 216 {
 217         eventfd_state_t *state;
 218         minor_t minor = getminor(dev);
 219         short revents = 0;
 220 
 221         state = ddi_get_soft_state(eventfd_softstate, minor);
 222 
 223         mutex_enter(&state->efd_lock);
 224 
 225         if (state->efd_value > 0)
 226                 revents |= POLLRDNORM | POLLIN;
 227 
 228         if (state->efd_value < EVENTFD_VALMAX)
 229                 revents |= POLLWRNORM | POLLOUT;
 230 
 231         if (!(*reventsp = revents & events) && !anyyet)

 232                 *phpp = &state->efd_pollhd;

 233 
 234         mutex_exit(&state->efd_lock);
 235 
 236         return (0);
 237 }
 238 
 239 /*ARGSUSED*/
 240 static int
 241 eventfd_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv)
 242 {
 243         eventfd_state_t *state;
 244         minor_t minor = getminor(dev);
 245 
 246         state = ddi_get_soft_state(eventfd_softstate, minor);
 247 
 248         switch (cmd) {
 249         case EVENTFDIOC_SEMAPHORE: {
 250                 mutex_enter(&state->efd_lock);
 251                 state->efd_semaphore ^= 1;
 252                 mutex_exit(&state->efd_lock);


   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2017 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * Support for the eventfd facility, a Linux-borne facility for user-generated
  18  * file descriptor-based events.
  19  */
  20 
  21 #include <sys/ddi.h>
  22 #include <sys/sunddi.h>
  23 #include <sys/eventfd.h>
  24 #include <sys/conf.h>
  25 #include <sys/vmem.h>
  26 #include <sys/sysmacros.h>
  27 #include <sys/filio.h>
  28 #include <sys/stat.h>
  29 #include <sys/file.h>
  30 
  31 struct eventfd_state;
  32 typedef struct eventfd_state eventfd_state_t;
  33 


 211 
 212 /*ARGSUSED*/
 213 static int
 214 eventfd_poll(dev_t dev, short events, int anyyet, short *reventsp,
 215     struct pollhead **phpp)
 216 {
 217         eventfd_state_t *state;
 218         minor_t minor = getminor(dev);
 219         short revents = 0;
 220 
 221         state = ddi_get_soft_state(eventfd_softstate, minor);
 222 
 223         mutex_enter(&state->efd_lock);
 224 
 225         if (state->efd_value > 0)
 226                 revents |= POLLRDNORM | POLLIN;
 227 
 228         if (state->efd_value < EVENTFD_VALMAX)
 229                 revents |= POLLWRNORM | POLLOUT;
 230 
 231         *reventsp = revents & events;
 232         if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
 233                 *phpp = &state->efd_pollhd;
 234         }
 235 
 236         mutex_exit(&state->efd_lock);
 237 
 238         return (0);
 239 }
 240 
 241 /*ARGSUSED*/
 242 static int
 243 eventfd_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv)
 244 {
 245         eventfd_state_t *state;
 246         minor_t minor = getminor(dev);
 247 
 248         state = ddi_get_soft_state(eventfd_softstate, minor);
 249 
 250         switch (cmd) {
 251         case EVENTFDIOC_SEMAPHORE: {
 252                 mutex_enter(&state->efd_lock);
 253                 state->efd_semaphore ^= 1;
 254                 mutex_exit(&state->efd_lock);