|
[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 |