Author: wulf
Date: Sun Nov 24 20:41:47 2019
New Revision: 355065
URL: https://svnweb.freebsd.org/changeset/base/355065

Log:
  Linux epoll: Don't deregister file descriptor after EPOLLONESHOT is fired
  
  Linux epoll does not remove descriptor after one-shot event has been 
triggered.
  Set EV_DISPATCH kqueue flag rather then EV_ONESHOT to get the same behavior.
  
  Required by Linux Steam client.
  
  PR:           240590
  Reported by:  Alex S <[email protected]>
  Reviewed by:  emaste, imp
  MFC after:    1 week
  Differential Revision:        https://reviews.freebsd.org/D22513

Modified:
  head/sys/compat/linux/linux_event.c

Modified: head/sys/compat/linux/linux_event.c
==============================================================================
--- head/sys/compat/linux/linux_event.c Sun Nov 24 19:18:12 2019        
(r355064)
+++ head/sys/compat/linux/linux_event.c Sun Nov 24 20:41:47 2019        
(r355065)
@@ -306,7 +306,7 @@ epoll_to_kevent(struct thread *td, struct file *epfp,
 
        /* flags related to how event is registered */
        if ((levents & LINUX_EPOLLONESHOT) != 0)
-               *kev_flags |= EV_ONESHOT;
+               *kev_flags |= EV_DISPATCH;
        if ((levents & LINUX_EPOLLET) != 0)
                *kev_flags |= EV_CLEAR;
        if ((levents & LINUX_EPOLLERR) != 0)
@@ -501,16 +501,17 @@ linux_epoll_ctl(struct thread *td, struct linux_epoll_
        case LINUX_EPOLL_CTL_ADD:
                /*
                 * kqueue_register() return ENOENT if event does not exists
-                * and the EV_ADD flag is not set.
+                * and the EV_ADD flag is not set. Reset EV_ENABLE flag to
+                * avoid accidental activation of fired oneshot events.
                 */
-               kev[0].flags &= ~EV_ADD;
+               kev[0].flags &= ~(EV_ADD | EV_ENABLE);
                error = kqfd_register(args->epfd, &kev[0], td, M_WAITOK);
                if (error != ENOENT) {
                        error = EEXIST;
                        goto leave0;
                }
                error = 0;
-               kev[0].flags |= EV_ADD;
+               kev[0].flags |= (EV_ADD | EV_ENABLE);
                break;
 
        case LINUX_EPOLL_CTL_DEL:
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to