]> xenbits.xensource.com Git - xen.git/commitdiff
libxl: handle POLLERR, POLLHUP, POLLNVAL properly
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 11 May 2012 17:58:55 +0000 (18:58 +0100)
committerIan Jackson <ian.jackson@eu.citrix.com>
Fri, 11 May 2012 17:58:55 +0000 (18:58 +0100)
Pass POLLERR and POLLHUP to fd callbacks, as is necessary.
Crash on POLLNVAL since that means our fds are messed up.

Document the behaviour (including the fact that poll sometimes sets
POLLHUP or POLLERR even if only POLLIN was requested.

Fix the one current fd callback to do something with POLLERR|POLLHUP.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
tools/libxl/libxl_event.c
tools/libxl/libxl_internal.h

index e11a4e7603b9a719a9305149a58ec45a0f20cf5e..5046938fd8190f7645a13ce190a7000f0d7d2d5c 100644 (file)
@@ -339,6 +339,9 @@ static void watchfd_callback(libxl__egc *egc, libxl__ev_fd *ev,
 {
     EGC_GC;
 
+    if (revents & (POLLERR|POLLHUP))
+        LIBXL__EVENT_DISASTER(egc, "unexpected poll event on watch fd", 0, 0);
+
     for (;;) {
         char **event = xs_check_watch(CTX->xsh);
         if (!event) {
@@ -743,7 +746,9 @@ static int afterpoll_check_fd(libxl__poller *poller,
         /* again, stale slot entry */
         return 0;
 
-    int revents = fds[slot].revents & events;
+    assert(!(fds[slot].revents & POLLNVAL));
+
+    int revents = fds[slot].revents & (events | POLLERR | POLLHUP);
     /* we mask in case requested events have changed */
 
     return revents;
index 8947ddd6fc20369c69fca2d8a19b44d3fa4ed356..74e640f74781c6394642f4a2f695e59c4fe8a899 100644 (file)
@@ -128,6 +128,11 @@ _hidden void libxl__alloc_failed(libxl_ctx *, const char *func,
 typedef struct libxl__ev_fd libxl__ev_fd;
 typedef void libxl__ev_fd_callback(libxl__egc *egc, libxl__ev_fd *ev,
                                    int fd, short events, short revents);
+  /* Note that revents may contain POLLERR or POLLHUP regardless of
+   * events; otherwise revents contains only bits in events.  Contrary
+   * to the documentation for poll(2), POLLERR and POLLHUP can occur
+   * even if only POLLIN was set in events.  (POLLNVAL is a fatal
+   * error and will cause libxl event machinery to fail an assertion.) */
 struct libxl__ev_fd {
     /* caller should include this in their own struct */
     /* read-only for caller, who may read only when registered: */