VPOLL(3) | Library Functions Manual | VPOLL(3) |
vpoll_create, vpoll_ctl, vpoll_close - generate synthetic events for poll/select/ppoll/pselect/epoll
#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);
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 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.
#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.
VirtualSquare. Project leader: Renzo Davoli.
December 2022 | VirtualSquare |