From: Ian Jackson Date: Wed, 26 Nov 2014 16:44:52 +0000 (+0000) Subject: libxl: events: Deregister xenstore watch fd when not needed X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~4021 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=77a1bf37790d8eb8fb99e7539a1591fdd2988f6d;p=xen.git libxl: events: Deregister xenstore watch fd when not needed We want to have no fd events registered when we are idle. In this patch, deal with the xenstore watch fd: * Track the total number of active watches. * When deregistering a watch, or when watch registration fails, check whether there are now no watches and if so deregister the fd. * On libxl teardown, the watch fd should therefore be unregistered. assert that this is the case. Signed-off-by: Ian Jackson Acked-by: Ian Campbell Tested-by: Ian Campbell Release-Acked-by: Konrad Rzeszutek Wilk --- diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 55ef5357b0..a2386215b5 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -164,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)); - libxl__ev_fd_deregister(gc, &ctx->watch_efd); + assert(!libxl__ev_fd_isregistered(&ctx->watch_efd)); libxl__ev_fd_deregister(gc, &ctx->evtchn_efd); libxl__ev_fd_deregister(gc, &ctx->sigchld_selfpipe_efd); diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c index 22b1227b48..da0a20e9c6 100644 --- a/tools/libxl/libxl_event.c +++ b/tools/libxl/libxl_event.c @@ -524,6 +524,13 @@ static char *watch_token(libxl__gc *gc, int slotnum, uint32_t counterval) return libxl__sprintf(gc, "%d/%"PRIx32, slotnum, counterval); } +static void watches_check_fd_deregister(libxl__gc *gc) +{ + assert(CTX->nwatches>=0); + if (!CTX->nwatches) + libxl__ev_fd_deregister(gc, &CTX->watch_efd); +} + int libxl__ev_xswatch_register(libxl__gc *gc, libxl__ev_xswatch *w, libxl__ev_xswatch_callback *func, const char *path /* copied */) @@ -579,6 +586,7 @@ int libxl__ev_xswatch_register(libxl__gc *gc, libxl__ev_xswatch *w, w->slotnum = slotnum; w->path = path_copy; w->callback = func; + CTX->nwatches++; libxl__set_watch_slot_contents(use, w); CTX_UNLOCK; @@ -590,6 +598,7 @@ int libxl__ev_xswatch_register(libxl__gc *gc, libxl__ev_xswatch *w, if (use) LIBXL_SLIST_INSERT_HEAD(&CTX->watch_freeslots, use, empty); free(path_copy); + watches_check_fd_deregister(gc); CTX_UNLOCK; return rc; } @@ -614,6 +623,8 @@ void libxl__ev_xswatch_deregister(libxl__gc *gc, libxl__ev_xswatch *w) libxl__ev_watch_slot *slot = &CTX->watch_slots[w->slotnum]; LIBXL_SLIST_INSERT_HEAD(&CTX->watch_freeslots, slot, empty); w->slotnum = -1; + CTX->nwatches--; + watches_check_fd_deregister(gc); } else { LOG(DEBUG, "watch w=%p: deregister unregistered", w); } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index a38f695751..9695f18759 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -352,7 +352,7 @@ struct libxl__ctx { LIBXL_TAILQ_HEAD(, libxl__ev_time) etimes; libxl__ev_watch_slot *watch_slots; - int watch_nslots; + int watch_nslots, nwatches; LIBXL_SLIST_HEAD(, libxl__ev_watch_slot) watch_freeslots; uint32_t watch_counter; /* helps disambiguate slot reuse */ libxl__ev_fd watch_efd;