libxl: fd events: Break out libxl__fd_poll_recheck
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 16 Apr 2015 18:23:26 +0000 (19:23 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 22 Apr 2015 13:53:46 +0000 (14:53 +0100)
Replaces two call sites where a rechecking poll() was open-coded.

No functional change, other than to highly unusual error path
diagnosis, and debug and error message output.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Jim Fehlig <jfehlig@suse.com>
CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tested-by: Jim Fehlig <jfehlig@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxl/libxl_event.c
tools/libxl/libxl_internal.h

index 595da2bd6188fa87226fa9aa576c6ae8c1066315..3efb357472bc7306390fc79533b99726573cd437 100644 (file)
@@ -236,6 +236,29 @@ void libxl__ev_fd_deregister(libxl__gc *gc, libxl__ev_fd *ev)
     CTX_UNLOCK;
 }
 
+short libxl__fd_poll_recheck(libxl__egc *egc, int fd, short events) {
+    struct pollfd check;
+    int r;
+
+    for (;;) {
+        check.fd = fd;
+        check.events = events;
+        r = poll(&check, 1, 0);
+        DBG("poll recheck fd=%d r=%d revents=%#x", fd, r, check.revents);
+        if (!r)
+            break;
+        if (r==1)
+            break;
+        assert(r<0);
+        if (errno != EINTR) {
+            LIBXL__EVENT_DISASTER(egc, "failed poll to check for fd", errno, 0);
+            return 0;
+        }
+    }
+    assert(!!r == !!check.revents);
+    return check.revents;
+}
+
 /*
  * timeouts
  */
@@ -661,9 +684,8 @@ static void evtchn_fd_callback(libxl__egc *egc, libxl__ev_fd *ev,
 {
     EGC_GC;
     libxl__ev_evtchn *evev;
-    int r, rc;
+    int rc;
     evtchn_port_or_error_t port;
-    struct pollfd recheck;
 
     rc = evtchn_revents_check(egc, revents);
     if (rc) return;
@@ -674,21 +696,10 @@ static void evtchn_fd_callback(libxl__egc *egc, libxl__ev_fd *ev,
          * held continuously since someone noticed the fd.  Normally
          * this wouldn't be a problem but evtchn devices don't always
          * honour O_NONBLOCK (see xenctrl.h). */
-
-        recheck.fd = fd;
-        recheck.events = POLLIN;
-        recheck.revents = 0;
-        r = poll(&recheck, 1, 0);
-        DBG("ev_evtchn recheck r=%d revents=%#x", r, recheck.revents);
-        if (r < 0) {
-            LIBXL__EVENT_DISASTER(egc,
-     "unexpected failure polling event channel fd for recheck",
-                                  errno, 0);
-            return;
-        }
-        if (r == 0)
+        revents = libxl__fd_poll_recheck(egc,fd,POLLIN);
+        if (!revents)
             break;
-        rc = evtchn_revents_check(egc, recheck.revents);
+        rc = evtchn_revents_check(egc, revents);
         if (rc) return;
 
         /* OK, that's that workaround done.  We can actually check for
@@ -1239,24 +1250,10 @@ void libxl_osevent_occurred_fd(libxl_ctx *ctx, void *for_libxl,
     if (!ev) goto out;
     if (ev->fd != fd) goto out;
 
-    struct pollfd check;
-    for (;;) {
-        check.fd = fd;
-        check.events = ev->events;
-        int r = poll(&check, 1, 0);
-        if (!r)
-            goto out;
-        if (r==1)
-            break;
-        assert(r<0);
-        if (errno != EINTR) {
-            LIBXL__EVENT_DISASTER(egc, "failed poll to check for fd", errno, 0);
-            goto out;
-        }
-    }
+    short current_revents = libxl__fd_poll_recheck(egc, ev->fd, ev->events);
 
-    if (check.revents)
-        ev->func(egc, ev, fd, ev->events, check.revents);
+    if (current_revents)
+        ev->func(egc, ev, fd, ev->events, current_revents);
 
  out:
     CTX_UNLOCK;
index 10d12526acab1e3837b5ad49d6c85251f55fa258..2986e3bbe12eaef24b01096db14c7d11e9d6b6e7 100644 (file)
@@ -1587,6 +1587,10 @@ _hidden int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
                                    libxl_device_disk *disk,
                                    libxl__device *device);
 
+/* Calls poll() again - useful to check whether a signaled condition
+ * is still true.  Cannot fail.  Returns currently-true revents. */
+_hidden short libxl__fd_poll_recheck(libxl__egc *egc, int fd, short events);
+
 _hidden char *libxl__uuid2string(libxl__gc *gc, const libxl_uuid uuid);
 
 struct libxl__xen_console_reader {