From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Jackson Subject: [PATCH 08/23] libxl: events: Provide libxl__xswait_* Date: Tue, 17 Dec 2013 18:35:22 +0000 Message-ID: <1387305337-15355-9-git-send-email-ian.jackson@eu.citrix.com> References: <1387305337-15355-1-git-send-email-ian.jackson@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1387305337-15355-1-git-send-email-ian.jackson@eu.citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xensource.com Cc: Shriram Rajagopalan , George Dunlap , Ian Jackson , Ian Campbell , Stefano Stabellini List-Id: xen-devel@lists.xenproject.org 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 CC: Stefano Stabellini CC: Ian Campbell --- 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 51d6c6d..36de135 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1068,6 +1068,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==ETIMEDOUT + * + * 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 + * + * 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