[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 05/22] libxl: events: Provide libxl__xswait_*
This is an ao utility for for conveniently doing a timed wait on xenstore. It handles setting up and cancelling the timeout, and also conveniently reads the key for you. No callers yet in this patch. Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CC: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v2: Fix doc comments to refer to correct rc values --- tools/libxl/libxl_aoutils.c | 77 ++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_internal.h | 52 ++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c index b4eb6e5..477717b 100644 --- a/tools/libxl/libxl_aoutils.c +++ b/tools/libxl/libxl_aoutils.c @@ -16,6 +16,83 @@ #include "libxl_internal.h" +/*----- xswait -----*/ + +static libxl__ev_xswatch_callback xswait_xswatch_callback; +static libxl__ev_time_callback xswait_timeout_callback; +static void xswait_report_error(libxl__egc*, libxl__xswait_state*, int rc); + +void libxl__xswait_init(libxl__xswait_state *xswa) +{ + libxl__ev_time_init(&xswa->time_ev); + libxl__ev_xswatch_init(&xswa->watch_ev); +} + +void libxl__xswait_stop(libxl__gc *gc, libxl__xswait_state *xswa) +{ + libxl__ev_time_deregister(gc, &xswa->time_ev); + libxl__ev_xswatch_deregister(gc, &xswa->watch_ev); +} + +bool libxl__xswait_inuse(const libxl__xswait_state *xswa) +{ + bool time_inuse = libxl__ev_time_isregistered(&xswa->time_ev); + bool watch_inuse = libxl__ev_xswatch_isregistered(&xswa->watch_ev); + assert(time_inuse == watch_inuse); + return time_inuse; +} + +int libxl__xswait_start(libxl__gc *gc, libxl__xswait_state *xswa) +{ + int rc; + + rc = libxl__ev_time_register_rel(gc, &xswa->time_ev, + xswait_timeout_callback, xswa->timeout_ms); + if (rc) goto err; + + rc = libxl__ev_xswatch_register(gc, &xswa->watch_ev, + xswait_xswatch_callback, xswa->path); + if (rc) goto err; + + return 0; + + err: + libxl__xswait_stop(gc, xswa); + return rc; +} + +void xswait_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *xsw, + const char *watch_path, const char *event_path) +{ + EGC_GC; + libxl__xswait_state *xswa = CONTAINER_OF(xsw, *xswa, watch_ev); + int rc; + const char *data; + + rc = libxl__xs_read_checked(gc, XBT_NULL, xswa->path, &data); + if (rc) { xswait_report_error(egc, xswa, rc); return; } + + xswa->callback(egc, xswa, 0, data); +} + +void xswait_timeout_callback(libxl__egc *egc, libxl__ev_time *ev, + const struct timeval *requested_abs) +{ + EGC_GC; + libxl__xswait_state *xswa = CONTAINER_OF(ev, *xswa, time_ev); + LOG(DEBUG, "%s: xswait timeout (path=%s)", xswa->what, xswa->path); + xswait_report_error(egc, xswa, ERROR_TIMEDOUT); +} + +static void xswait_report_error(libxl__egc *egc, libxl__xswait_state *xswa, + int rc) +{ + EGC_GC; + libxl__xswait_stop(gc, xswa); + xswa->callback(egc, xswa, rc, 0); +} + + /*----- data copier -----*/ void libxl__datacopier_init(libxl__datacopier_state *dc) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 60a39ed..a208be7 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1100,6 +1100,58 @@ _hidden int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int num); _hidden int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid); +/*----- xswait: wait for a xenstore node to be suitable -----*/ + +typedef struct libxl__xswait_state libxl__xswait_state; + +/* + * rc describes the circumstances of this callback: + * + * rc==0 + * + * The xenstore path (may have) changed. It has been read for + * you. The result is in data (allocated from the ao gc). + * data may be NULL, which means that the xenstore read gave + * ENOENT. + * + * If you are satisfied, you MUST call libxl__xswait_stop. + * Otherwise, xswait will continue waiting and watching and + * will call you back later. + * + * rc==ERROR_TIMEDOUT + * + * The specified timeout was reached. + * This has NOT been logged (except to the debug log). + * xswait will not continue (but calling libxl__xswait_stop is OK). + * + * rc!=0, !=ERROR_TIMEDOUT + * + * Some other error occurred. + * This HAS been logged. + * xswait will not continue (but calling libxl__xswait_stop is OK). + * + */ +typedef void libxl__xswait_callback(libxl__egc *egc, + libxl__xswait_state *xswa, int rc, const char *data); + +struct libxl__xswait_state { + /* caller must fill these in, and they must all remain valid */ + libxl__ao *ao; + const char *what; /* for error msgs: noun phrase, what we're waiting for */ + const char *path; + int timeout_ms; /* as for poll(2) */ + libxl__xswait_callback *callback; + /* remaining fields are private to xswait */ + libxl__ev_time time_ev; + libxl__ev_xswatch watch_ev; +}; + +void libxl__xswait_init(libxl__xswait_state*); +void libxl__xswait_stop(libxl__gc*, libxl__xswait_state*); /*idempotent*/ +bool libxl__xswait_inuse(const libxl__xswait_state *ss); + +int libxl__xswait_start(libxl__gc*, libxl__xswait_state*); + /* *----- spawn ----- * -- 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 |