c - How to detect empty epoll set -


i'm learning use epoll, , wrote following example

#include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <unistd.h>  int main() {     int epfd;     struct epoll_event ev;     struct epoll_event ret;     char buf[200];     int n,k,t;      epfd = epoll_create(100);     assert(0 ==             fcntl(0, f_setfl, fcntl(0, f_getfl) | o_nonblock)           );      ev.data.fd = 0;     ev.events = epollin  | epollet;      if(epoll_ctl(epfd, epoll_ctl_add, 0, &ev) != 0)         perror("epoll_ctl");       while((n = epoll_wait(epfd, &ret, 1, -1)) > 0) {         printf("tick!\n");          if(ret.data.fd == 0) {             k=0;             while((t=read(0, buf, 100)) > 0) {                 k+=t;             }                 if(k == 0) {                 close(0);                 printf("stdin done\n");             }         }        }      perror("epoll");     return 0; } 

if try running in terminal won't work since fds 0, 1 , 2 point same open file, close(0) won't remove stdin epoll set. can around doing "cat | ./a.out". dirty trick, know, setting small example named pipes or sockets more complicated.

now, works , file removed epoll set, next epoll_wait call blocks permanently since it's on empty set! need detect if epoll file descriptor (epfd) empty epoll set.

how can around this? (in general manner, not calling exit when stdin done) thanks!

basically, if you're using epoll "correctly", should never have situation of unexpectedly empty epoll set. should know when there more or not. well, or that's theory @ least. let me review it:

you using epollet here (which is, imho, right think in general). means file descriptor 0 removed epoll when returned in &ret. @ point should handle reading amount of data 0, do, "re-arming" adding again file descriptor 0 epoll (unless closed of course). example of how supposed work, remove inner loop , do:

k = read(0, buf, 100); 

reading maximum of 100 bytes. idea if pipe file bigger that, should go several times through whole loop. in order make work, if k > 0, after handle k bytes, need call epoll_ctl(..epoll_ctl_add..) again.

note annoying detail: it's possible read() returns 0 bytes without meaning file or socket @ end. check if errno == eagain || errno == ewouldblock. detect case, , epoll_ctl(..epoll_ctl_add..) again.


Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -