[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |