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>

@@ -20,10 +20,11 @@
  */
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
  */
 
 
 #include <sys/errno.h>
 #include <sys/types.h>

@@ -654,18 +655,18 @@
         if (state == NULL) {
                 return (EBADF);
         }
 
         if (((events & (POLLIN | POLLRDNORM)) == 0) && !anyyet) {
-                *reventsp = 0;
                 return (EINVAL);
         }
 
         /*
          * if we pushed requests on the user ring since the last poll, wakeup
          * the user app
          */
+        *reventsp = 0;
         usring = &state->bt_user_ring;
         if (usring->ur_prod_polled != usring->ur_ring.req_prod_pvt) {
 
                 /*
                  * XXX - is this faster here or xpvtap_user_request_push??

@@ -675,18 +676,15 @@
                  */
                 RING_PUSH_REQUESTS(&usring->ur_ring);
 
                 usring->ur_prod_polled = usring->ur_ring.sring->req_prod;
                 *reventsp =  POLLIN | POLLRDNORM;
+        }
 
-        /* no new requests */
-        } else {
-                *reventsp = 0;
-                if (!anyyet) {
+        if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
                         *phpp = &state->bt_pollhead;
                 }
-        }
 
         return (0);
 }