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>
This commit is contained in:
Ian Jackson authored and Ian Campbell committed 2015-04-22 14:53:46 +01:00
1 parent 269ac7369d
commit 12f005c19d
2 files changed
+34 -33

No files matched your search

+30 -33
View 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;
+4
View 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 {
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.