Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with listening socket by epoll

Tags:

c

sockets

epoll

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?

like image 955
Je Rog Avatar asked Jun 19 '11 09:06

Je Rog


1 Answers

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.

like image 189
Mat Avatar answered Sep 20 '22 00:09

Mat