Provided by: libvpoll-dev_0.1-2ubuntu2_amd64 bug

NAME

       vpoll_create, vpoll_ctl, vpoll_close - generate synthetic events for poll/select/ppoll/pselect/epoll

SYNOPSIS

       #include <vpoll.h>

       int vpoll_create(uint32_t init_events, int flags);

       int vpoll_ctl(int fd, int op, uint32_t events);

       int vpoll_close(int fd);

DESCRIPTION

       This   library   permits  one  to  create  a  vpoll  file  descriptor  "vpollfd"  that  can  be  used  in
       poll/select/ppoll/pselect/epoll(2) system calls. The events reported by a can be controlled by vpoll_ctl.
       vpoll encodes the events using the same flags EPOLL* defined in epoll_ctl(2).

       The library uses the vpoll extension for eventfd if the  kernel  provides  it  otherwise  it  (partially)
       emulates  the  feature using socketpair(2). The emulation supports only EPOLLIN, EPOLLOUT flags and a non
       standard version of EPOLLHUP/EPOLLRDHUP.

       vpoll_create
              This function creates a "vpollfd". The argument init_events is used to set the  initial  state  of
              events. The following value can be included in flags:

              FD_CLOEXEC:  Set  the  close-on-exec  flag  on the new file descriptor. See the description of the
              O_CLOEXEC flag in open(2) for reasons why this may be useful.

       vpoll_ctl
              This function changes the set of pending events reported by a "vpollfd". The argument op can  take
              the following values:

              VPOLL_CTL_ADDEVENTS: the events set in the argument events are added to the set of pending events.

              VPOLL_CTL_DELEVENTS:  the  events  set  in the argument events are deleted from the set of pending
              events.

              VPOLL_CTL_SETEVENTS: the value of the argument events is assigned to the set of pending events.

       vpoll_close
              This function closes the vpoll file descritor.

RETURN VALUE

       vpoll_create returns the new file descriptor, or -1 if an error occurred (in which  case,  errno  is  set
       appropriately)

       vpoll_ctl  and  vpoll_close  return  zero  in case of success. On error, -1 is returned, and errno is set
       appropriately.

EXAMPLE

       #define _GNU_SOURCE
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <fcntl.h>
       #include <errno.h>
       #include <sys/epoll.h>
       #include <vpoll.h>

       int main(int argc, char *argv[]) {
           int vpollfd = vpoll_create(0, FD_CLOEXEC);
           int epfd = epoll_create1(EPOLL_CLOEXEC);
           struct epoll_event reqevents={EPOLLIN | EPOLLRDHUP | EPOLLERR |
               EPOLLOUT | EPOLLHUP | EPOLLPRI};
           epoll_ctl(epfd,  EPOLL_CTL_ADD, vpollfd, &reqevents);
           switch (fork()) {
               case 0:
                   sleep(3);
                   vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLIN);
                   sleep(3);
                   vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLIN);
                   sleep(3);
                   vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLOUT);
                   sleep(3);
                   vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLHUP);
                   sleep(3);
                   exit(0);
               default:
                   while (1) {
                       struct epoll_event ev;
                       int n = epoll_wait(epfd, &ev, 1, 1000);
                       if (n < 0) {
                           perror("epoll_wait");
                           break;
                       }
                       if (n > 0) {
                           printf("GOT event %x\n", ev.events);
                           vpoll_ctl(vpollfd, VPOLL_CTL_DELEVENTS, ev.events);
                           if (ev.events & EPOLLHUP)
                                   break;
                       } else {
                           printf("timeout\n");
                       }
                   }
                   break;
               case -1:
                   printf("fork error\n");
           }
           vpoll_close(vpollfd);
           close(epfd);
           return 0;
       }

       On a machine running a Linux Kernel providing eventfd/vpoll the output of this program is:

           timeout
           timeout
           GOT event 1
           timeout
           timeout
           GOT event 1
           timeout
           timeout
           GOT event 4
           timeout
           timeout
           GOT event 10

       Instead when the demo program runs using the emulation layer the output is:

           timeout
           timeout
           GOT event 1
           timeout
           timeout
           GOT event 1
           timeout
           timeout
           GOT event 4
           timeout
           timeout
           GOT event 2011

       In fact, the emulator uses a socketpair to generate the events. Hangup is emulated by closing  the  other
       end of the socketpair: this generates EPOLLHUP as well as EPOLLIN and EPOLLRDHUP.

AUTHOR

       VirtualSquare. Project leader: Renzo Davoli.

VirtualSquare                                     October 2019                                          VPOLL(3)