5

All below is from man epoll page:

The function do_use_fd() uses the new ready file descriptor until EAGAIN is returned by either read(2) or write(2).

Code example for ET triggered :

   for(;;) {
       nfds = epoll_wait(kdpfd, events, maxevents, -1);

       for(n = 0; n < nfds; ++n) {
           if(events[n].data.fd == listener) {
               client = accept(listener, (struct sockaddr *) &local,
                               &addrlen);
               if(client < 0){
                   perror("accept");
                   continue;
               }
               setnonblocking(client);
               ev.events = EPOLLIN | EPOLLET;
               ev.events = EPOLLIN | EPOLLET;
               ev.data.fd = client;
               if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {
                   fprintf(stderr, "epoll set insertion error: fd=%d\n",
                           client);
                   return -1;
               }
           }
           else
               do_use_fd(events[n].data.fd);
       }
   }

So for read/write operation,we should do it by looping until a EAGAIN is received;but why it's not the case for accept?

IMO the above code will miss some requests when there're multiple client sockets waiting to be accepted, as it accepts only 1 client socket, we should also wrap it in a loop until EAGAIN received.

Or maybe is there something I'm missing?

Je Rog
  • 5,675
  • 8
  • 39
  • 47

1 Answers1

6

Look at how the listener socket is added to the epollfd:

ev.events = EPOLLIN;       // this is the crucial bit
ev.data.fd = listen_sock;

It's not added in edge-triggered, it's added in level-triggered. So no need for a loop until EAGAIN on that one.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • @Mat,if `listen_sock` is added to epollfd in ET mode(`|EPOLLET`),how will you deal with it? My above code is wrong,right? – Je Rog Jun 19 '11 at 09:58
  • the code in the man page is correct because it does _not_ set ET mode on the listener socket. If you add your listener in ET mode, then yes you need to take extra precautions and loop until EAGAIN. Be careful with starvation though. – Mat Jun 19 '11 at 10:04
  • @Mat,is the above code about `listen_sock` right quoted from the `man epoll` page? – Je Rog Jun 19 '11 at 10:07
  • pretty much. what you posted lacks some error checking and you've got a line that's pasted twice, but apart from that it's the same structure. Since you quoted that man page, I had assumed that you had the same setup code as in there. – Mat Jun 19 '11 at 10:12
  • @Mat,seems my man is outdated , `man, version 1.6d`,doesn't have that code about `listen_sock`. – Je Rog Jun 19 '11 at 10:28
  • [`man epoll`](http://www.kernel.org/doc/man-pages/online/pages/man4/epoll.4.html). The man pages that are available on kernel.org are usually up to date. – Mat Jun 19 '11 at 10:30
  • @Mat ,will `LT` be much less efficient than `ET`? – Je Rog Jun 19 '11 at 10:40
  • There is no answer to that question, it depends on your specific workload. – Mat Jun 19 '11 at 10:41