Referencs: bsc#955104 bsc#959552 bsc#993665 bsc#959330 bsc#990500

commit 12f005c19de3d094c18322aae08f07c1949d9f53
Author: Ian Jackson <ian.jackson@eu.citrix.com>
Date:   Thu Apr 16 19:23:26 2015 +0100

    libxl: fd events: Break out libxl__fd_poll_recheck
    
    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>

Index: xen-4.5.3-testing/tools/libxl/libxl_event.c
===================================================================
--- xen-4.5.3-testing.orig/tools/libxl/libxl_event.c
+++ xen-4.5.3-testing/tools/libxl/libxl_event.c
@@ -240,6 +240,29 @@ void libxl__ev_fd_deregister(libxl__gc *
     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
  */
@@ -665,9 +688,8 @@ static void evtchn_fd_callback(libxl__eg
 {
     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;
@@ -678,21 +700,10 @@ static void evtchn_fd_callback(libxl__eg
          * 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
@@ -1245,24 +1256,10 @@ void libxl_osevent_occurred_fd(libxl_ctx
     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: xen-4.5.3-testing/tools/libxl/libxl_internal.h
===================================================================
--- xen-4.5.3-testing.orig/tools/libxl/libxl_internal.h
+++ xen-4.5.3-testing/tools/libxl/libxl_internal.h
@@ -1578,6 +1578,10 @@ _hidden int libxl__device_from_disk(libx
                                    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 {
