diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 8f06043c75..50a8928a48 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -118,8 +118,6 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version, rc = ERROR_FAIL; goto out; } - rc = libxl__ctx_evtchn_init(gc); - *pctx = ctx; return 0; @@ -166,7 +164,7 @@ int libxl_ctx_free(libxl_ctx *ctx) for (i = 0; i < ctx->watch_nslots; i++) assert(!libxl__watch_slot_contents(gc, i)); assert(!libxl__ev_fd_isregistered(&ctx->watch_efd)); - libxl__ev_fd_deregister(gc, &ctx->evtchn_efd); + assert(!libxl__ev_fd_isregistered(&ctx->evtchn_efd)); assert(!libxl__ev_fd_isregistered(&ctx->sigchld_selfpipe_efd)); /* Now there should be no more events requested from the application: */ diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c index da0a20e9c6..a36e6d98ff 100644 --- a/tools/libxl/libxl_event.c +++ b/tools/libxl/libxl_event.c @@ -739,10 +739,6 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) { rc = libxl_fd_set_nonblock(CTX, fd, 1); if (rc) goto out; - rc = libxl__ev_fd_register(gc, &CTX->evtchn_efd, - evtchn_fd_callback, fd, POLLIN); - if (rc) goto out; - CTX->xce = xce; return 0; @@ -751,6 +747,12 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) { return rc; } +static void evtchn_check_fd_deregister(libxl__gc *gc) +{ + if (CTX->xce && LIBXL_LIST_EMPTY(&CTX->evtchns_waiting)) + libxl__ev_fd_deregister(gc, &CTX->evtchn_efd); +} + int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev) { int r, rc; @@ -758,6 +760,15 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev) DBG("ev_evtchn=%p port=%d wait (was waiting=%d)", evev, evev->port, evev->waiting); + rc = libxl__ctx_evtchn_init(gc); + if (rc) goto out; + + if (!libxl__ev_fd_isregistered(&CTX->evtchn_efd)) { + rc = libxl__ev_fd_register(gc, &CTX->evtchn_efd, evtchn_fd_callback, + xc_evtchn_fd(CTX->xce), POLLIN); + if (rc) goto out; + } + if (evev->waiting) return 0; @@ -773,6 +784,7 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev) return 0; out: + evtchn_check_fd_deregister(gc); return rc; } @@ -786,6 +798,7 @@ void libxl__ev_evtchn_cancel(libxl__gc *gc, libxl__ev_evtchn *evev) evev->waiting = 0; LIBXL_LIST_REMOVE(evev, entry); + evtchn_check_fd_deregister(gc); } /*