Tanaka,

I've only looked briefly at your mail.  But is the problem that your
application is not checking for EPOLLRDHUP, available since kernel 2.6.17?
 See (a recent version of) the epoll_ctl(2) man page for details.

Cheers,

Michael

Tanaka Akira wrote:
> 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.)

-- 
Michael Kerrisk
maintainer of Linux man pages Sections 2, 3, 4, 5, and 7

Want to help with man page maintenance?  Grab the latest tarball at
http://www.kernel.org/pub/linux/docs/manpages/
read the HOWTOHELP file and grep the source files for 'FIXME'.


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to