mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
libxl: events: Deregister evtchn fd when not needed
We want to have no fd events registered when we are idle. In this patch, deal with the evtchn fd: * Defer setup of the evtchn handle to the first use. * Defer registration of the evtchn fd; register as needed on use. * When cancelling an evtchn wait, or when wait setup fails, check whether there are now no evtchn waits and if so deregister the fd. * On libxl teardown, the evtchn fd should therefore be unregistered. assert that this is the case. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> Tested-by: Ian Campbell <ian.campbell@citrix.com> Release-Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- v2: Do not bother putting evtchn_fd in the ctx; instead, get it from xc_evtchn_fd when we need it. (Cosmetic.) Do not register the evtchn fd multiple times: check it's not registered before we call libxl__ev_fd_register. (Bugfix.)
This commit is contained in:
1 parent
5a96825745
commit
2ffeb5d7f5
2 files changed
+18
-7
No files matched your search
+1
-3
@@ -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: */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||