From: Martin Mares Date: Fri, 19 Aug 2011 10:29:34 +0000 (+0200) Subject: Main: Clean up handling of poll flags X-Git-Tag: v5.0~112 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=cd7dce2a6e06894c5e8c24ae399fe1900d6462e1;p=libucw.git Main: Clean up handling of poll flags - We no longer include POLLERR and POLLHUP in the set of requested events. The standard (SUSv2) says they will be delivered regardless of the event mask chosen. - POLLERR is an output event, so we call only the write handler. - POLLHUP is documented as an output event, but it sometimes signals events which we would like to process by the input handler. The situations when POLLHUP is generated include: * on reading end of a pipe when the writing end has been closed -> we would like to call read handler and get EOF (write handler does not exist) * on writing end of a pipe when the reading end has been closed -> we would like to call write handler (read handler does not exist) * on a R/W socket when the other end has been closed -> better call read handler to get an EOF * on a tty which has been hanged up -> probably the same as a R/W socket We have therefore decided to call the read handler, but fall back to the write handler if the read handler does not exist. - When a handler decided to remove itself (but keep the main_file), we could have entered an infinite loop. This no longer happens. --- diff --git a/ucw/mainloop.c b/ucw/mainloop.c index 0d7d1e16..b7ee5bf9 100644 --- a/ucw/mainloop.c +++ b/ucw/mainloop.c @@ -306,9 +306,9 @@ file_want_events(struct main_file *fi) { uns events = 0; if (fi->read_handler) - events |= POLLIN | POLLHUP | POLLERR; + events |= POLLIN; if (fi->write_handler) - events |= POLLOUT | POLLERR; + events |= POLLOUT; return events; } @@ -856,20 +856,20 @@ main_loop(void) struct main_file *fi; while (fi = clist_head(&m->file_active_list)) { - if (fi->events & (POLLIN | POLLHUP | POLLERR)) + if (fi->write_handler && (fi->events & (POLLOUT | POLLHUP | POLLERR))) { - fi->events &= ~(POLLIN | POLLHUP | POLLERR); + fi->events &= ~(POLLOUT | POLLHUP | POLLERR); do - DBG("MAIN: Read event on fd %d", fi->fd); - while (fi->read_handler && fi->read_handler(fi)); + DBG("MAIN: Write event on fd %d", fi->fd); + while (fi->write_handler && fi->write_handler(fi)); continue; } - if (fi->events & (POLLOUT | POLLERR)) + if (fi->read_handler && (fi->events & (POLLIN | POLLHUP))) { - fi->events &= ~(POLLOUT | POLLERR); + fi->events &= ~(POLLIN | POLLHUP); do - DBG("MAIN: Write event on fd %d", fi->fd); - while (fi->write_handler && fi->write_handler(fi)); + DBG("MAIN: Read event on fd %d", fi->fd); + while (fi->read_handler && fi->read_handler(fi)); continue; } clist_remove(&fi->n);