]> mj.ucw.cz Git - libucw.git/commitdiff
Main: Clean up handling of poll flags
authorMartin Mares <mj@ucw.cz>
Fri, 19 Aug 2011 10:29:34 +0000 (12:29 +0200)
committerMartin Mares <mj@ucw.cz>
Fri, 19 Aug 2011 10:29:34 +0000 (12:29 +0200)
- 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.

ucw/mainloop.c

index 0d7d1e164278b118e06d64c818ca58b86f9d364a..b7ee5bf989c52baac52b3e988d567e20ffea415c 100644 (file)
@@ -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);