Hello Olaf,

Olaf van der Spek wrote:
On Sat, Nov 1, 2008 at 8:38 PM, Michael Kerrisk
<[EMAIL PROTECTED]> wrote:
And then it'd be nice to give an example where it does use edge-triggering as 
well.
This would serve to make the example longer, but I'm not sure that it
would provide any real learning benefit.  (I'm open to (good)
arguments to the contrary, especially if accompanied by a suitable
patch.)

I'm wondering about the case where accept() returns EMFILE. In that
case, the example currently misbehaves (it does a busy loop).

Agreed -- that error is not properly handled.  (There is the same
problem for ENFILE.)  Thanks for spotting that.

I'm not sure how epoll behaves in this case and a solution doesn't
appear to be trivial.

Well, epoll_wait(2) is just going to behave as usual: it tells us that the 
listening
socket fd is ready.  Then the accept() fails with EMFILE.

I think the simplest thing here is to change the "continue;" in the error
handling after accept() to "exit(EXIT_FAILURE);", and that's what I've done
for man-pages-3.13.

I also added error handling for the epoll_wait() call.

The code of the example by now reads as below.

Cheers,

Michael


           #define MAX_EVENTS 10
           struct epoll_event ev, events[MAX_EVENTS];
           int listen_sock, conn_sock, nfds, epollfd;

           /* Set up listening socket, 'listen_sock' (socket(),
              bind(), listen()) */

           epollfd = epoll_create(10);
           if (epollfd == -1) {
               perror("epoll_create");
               exit(EXIT_FAILURE);
           }

           ev.events = EPOLL_IN;
           ev.data.fd = listen_sock;
           if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
               perror("epoll_ctl: listen_sock");
               exit(EXIT_FAILURE);
           }

           for (;;) {
               nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
               if (nfds == -1) {
                   perror("epoll_pwait");
                   exit(EXIT_FAILURE);
               }

               for (n = 0; n < nfds; ++n) {
                   if (events[n].data.fd == listen_sock) {
                       conn_sock = accept(listen_sock,
                                       (struct sockaddr *) &local, &addrlen);
                       if (conn_sock == -1) {
                           perror("accept");
                           exit(EXIT_FAILURE);
                       }
                       setnonblocking(conn_sock);
                       ev.events = EPOLLIN | EPOLLET;
                       ev.data.fd = conn_sock;
                       if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                                   &ev) == -1) {
                           perror("epoll_ctl: conn_sock);
                           exit(EXIT_FAILURE);
                       }
                   } else {
                       do_use_fd(events[n].data.fd);
                   }
               }
           }




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

Reply via email to