File 5537a7ea-libxl-fd-events1.patch of Package xen.6117
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.5-testing/tools/libxl/libxl_event.c
===================================================================
--- xen-4.5.5-testing.orig/tools/libxl/libxl_event.c
+++ xen-4.5.5-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.5-testing/tools/libxl/libxl_internal.h
===================================================================
--- xen-4.5.5-testing.orig/tools/libxl/libxl_internal.h
+++ xen-4.5.5-testing/tools/libxl/libxl_internal.h
@@ -1581,6 +1581,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 {