Package: manpages Version: 2.39-1 I think epoll(4)'s A9 has a problem.
Q9 Do I need to continuously read/write an fd until EAGAIN when using the EPOLLET flag ( Edge Triggered behaviour ) ? A9 No you don't. Receiving an event from epoll_wait(2) should sug- gest to you that such file descriptor is ready for the requested I/O operation. You have simply to consider it ready until you will receive the next EAGAIN. When and how you will use such file descriptor is entirely up to you. Also, the condition that the read/write I/O space is exhausted can be detected by check- ing the amount of data read/write from/to the target file descriptor. For example, if you call read(2) by asking to read a certain amount of data and read(2) returns a lower number of bytes, you can be sure to have exhausted the read I/O space for such file descriptor. Same is valid when writing using the write(2) function. The problem is the sentence about read(2): For example, if you call read(2) by asking to read a certain amount of data and read(2) returns a lower number of bytes, you can be sure to have exhausted the read I/O space for such file descriptor. When the waiting fd is a socket and other end sends some data and half close it, epoll_wait notified EPOLLIN. If client reads the data and the data is smaller than the buffer length, the above condition met. So epoll_wait should be callable according to above description. But epoll_wait blocks indefinitely and doesn't notify EOF. % cat tst.c #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> int main() { int ret; int fds[2], r, w; int ep; struct epoll_event ev; #define BUFLEN 4096 char buf[BUFLEN]; /* allocate socket pair */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) { perror("socketpair"); exit(1); } r = fds[0]; w = fds[1]; /* write "abc" to writing side */ ret = write(w, "abc", 3); if (ret == -1) { perror("write"); exit(1); } if (ret != 3) { fprintf(stderr, "unexpected write: %d\n", ret); exit(1); } /* half close on writing side */ if (shutdown(w, SHUT_WR) == -1) { perror("shutdown"); exit(1); } /* allocate epoll queue */ ep = epoll_create(1); if (ep == -1) { perror("epoll_create"); exit(1); } /* register the reading side socket in edge trigger style */ ev.events = EPOLLIN|EPOLLET; ev.data.fd = r; ret = epoll_ctl(ep, EPOLL_CTL_ADD, r, &ev); /* first epoll_wait: it notifies some data ("abc") available. */ ret = epoll_wait(ep, &ev, 1, -1); if (ret == -1) { perror("epoll_wait"); exit(1); } if (ret != 1) { fprintf(stderr, "unexpected epoll_wait: %d\n", ret); exit(1); } /* the notified event is just EPOLLIN. (No EPOLLHUP) */ if (ev.events != EPOLLIN) { fprintf(stderr, "unexpected events: %d\n", ev.events); exit(1); } /* consume "abc". */ ret = read(r, buf, BUFLEN); if (ret == -1) { perror("read"); exit(1); } if (ret != 3) { fprintf(stderr, "unexpected read: %d\n", ret); exit(1); } /* According to A9 of epoll(4), ret < BUFLEN means the kernel I/O space of the r is exhausted. * So epoll_wait should be callable safely at this point. * But it blocks indefinitely. */ ret = epoll_wait(ep, &ev, 1, -1); if (ret == -1) { perror("epoll_wait"); exit(1); } return 0; } % gcc tst.c % strace ./a.out ... socketpair(PF_FILE, SOCK_STREAM, 0, [3, 4]) = 0 write(4, "abc", 3) = 3 shutdown(4, 1 /* send */) = 0 epoll_create(1) = 6 epoll_ctl(6, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLET, {u32=3, u64=12654713184490356739}}) = 0 epoll_wait(6, {{EPOLLIN, {u32=3, u64=12654713184490356739}}}, 1, -1) = 1 read(3, "abc", 4096) = 3 epoll_wait(6, The strace result shows that second epoll_wait blocks. I think read(2) should be called until EAGAIN even if read(2) doesn't fill up the buffer. (The sample code doesn't use O_NONBLOCK, though.) -- Tanaka Akira -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]