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:
-
timeouttimeoutGOT event 1timeouttimeoutGOT event 1timeouttimeoutGOT event 4timeouttimeoutGOT event 10
Instead when the demo program runs using the emulation layer the output is:
-
timeouttimeoutGOT event 1timeouttimeoutGOT event 1timeouttimeoutGOT event 4timeouttimeoutGOT 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.