[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/2] libxl: fd events: Document spurious callbacks, break out libxl__ev_fd_recheck



No functional change, other than to debug and error message output.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
 tools/libxl/libxl_event.c    |   39 +++++++++++++++++++++++----------------
 tools/libxl/libxl_internal.h |    8 ++++++++
 2 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 595da2b..9ede135 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -236,6 +236,25 @@ void libxl__ev_fd_deregister(libxl__gc *gc, libxl__ev_fd 
*ev)
     CTX_UNLOCK;
 }
 
+short libxl__ev_fd_recheck(libxl__egc *egc, libxl__ev_fd *ev) {
+    struct pollfd recheck;
+    int r;
+
+    recheck.fd = ev->fd;
+    recheck.events = ev->events;
+    recheck.revents = 0;
+    r = poll(&recheck, 1, 0);
+    DBG("ev_fd=%p recheck fd=%d r=%d revents=%#x", ev, ev->fd,
+        r, recheck.revents);
+    if (r < 0) {
+        LIBXL__EVENT_DISASTER(egc, "unexpected failure rechecking fd",
+                              errno, 0);
+        return 0;
+    }
+    assert(!!r == !!recheck.revents);
+    return recheck.revents;
+}
+
 /*
  * timeouts
  */
@@ -661,9 +680,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 +692,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__ev_fd_recheck(egc,ev);
+        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
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 9c22309..d3a5fba 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -175,6 +175,9 @@ typedef void libxl__ev_fd_callback(libxl__egc *egc, 
libxl__ev_fd *ev,
    * even if only POLLIN was set in events.  (POLLNVAL is a fatal
    * error and will cause libxl event machinery to fail an assertion.)
    *
+   * Note that spurious callbacks are possible.  If this is a problem,
+   * use libxl__ev_fd_recheck;
+   *
    * It is not permitted to listen for the same or overlapping events
    * on the same fd using multiple different libxl__ev_fd's.
    */
@@ -788,6 +791,11 @@ static inline void libxl__ev_fd_init(libxl__ev_fd *efd)
 static inline int libxl__ev_fd_isregistered(const libxl__ev_fd *efd)
                     { return efd->fd >= 0; }
 
+/* Calls poll() again - useful to check whether this was a spurious
+ * wakeup.  Cannot fail.  Returns currently-true revents. */
+short libxl__ev_fd_recheck(libxl__egc *egc, libxl__ev_fd *ev);
+
+
 _hidden int libxl__ev_time_register_rel(libxl__gc*, libxl__ev_time *ev_out,
                                         libxl__ev_time_callback*,
                                         int milliseconds /* as for poll(2) */);
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.