[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] libxl: Introduce libxl__ev_devstate
# HG changeset patch # User Ian Jackson <ian.jackson@xxxxxxxxxxxxx> # Date 1327683685 0 # Node ID 0fc9948457962514ab9a9a4bb9ed0bf3695dee1b # Parent ccc3656225ef5062ee3efbf21be31e69feffc632 libxl: Introduce libxl__ev_devstate Provide a new-style asynchronous facility for waiting for device states on xenbus. This will replace libxl__wait_for_device_state, after the callers have been updated in later patches. Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Committed-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> --- diff -r ccc3656225ef -r 0fc994845796 tools/libxl/libxl_event.c --- a/tools/libxl/libxl_event.c Fri Jan 27 17:01:24 2012 +0000 +++ b/tools/libxl/libxl_event.c Fri Jan 27 17:01:25 2012 +0000 @@ -507,6 +507,81 @@ } /* + * waiting for device state + */ + +static void devstate_watch_callback(libxl__egc *egc, libxl__ev_xswatch *watch, + const char *watch_path, const char *event_path) +{ + EGC_GC; + libxl__ev_devstate *ds = CONTAINER_OF(watch, *ds, watch); + int rc; + + char *sstate = libxl__xs_read(gc, XBT_NULL, watch_path); + if (!sstate) { + if (errno == ENOENT) { + LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, "backend %s wanted state %d" + " but it was removed", watch_path, ds->wanted); + rc = ERROR_INVAL; + } else { + LIBXL__LOG_ERRNO(CTX, LIBXL__LOG_ERROR, "backend %s wanted state" + " %d but read failed", watch_path, ds->wanted); + rc = ERROR_FAIL; + } + } else { + int got = atoi(sstate); + if (got == ds->wanted) { + LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, "backend %s wanted state %d ok", + watch_path, ds->wanted); + rc = 0; + } else { + LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, "backend %s wanted state %d" + " still waiting state %d", watch_path, ds->wanted, got); + return; + } + } + libxl__ev_devstate_cancel(gc, ds); + ds->callback(egc, ds, rc); +} + +static void devstate_timeout(libxl__egc *egc, libxl__ev_time *ev, + const struct timeval *requested_abs) +{ + EGC_GC; + libxl__ev_devstate *ds = CONTAINER_OF(ev, *ds, timeout); + LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, "backend %s wanted state %d " + " timed out", ds->watch.path, ds->wanted); + libxl__ev_devstate_cancel(gc, ds); + ds->callback(egc, ds, ERROR_TIMEDOUT); +} + +int libxl__ev_devstate_wait(libxl__gc *gc, libxl__ev_devstate *ds, + libxl__ev_devstate_callback cb, + const char *state_path, int state, int milliseconds) +{ + int rc; + + libxl__ev_time_init(&ds->timeout); + libxl__ev_xswatch_init(&ds->watch); + ds->wanted = state; + ds->callback = cb; + + rc = libxl__ev_time_register_rel(gc, &ds->timeout, devstate_timeout, + milliseconds); + if (rc) goto out; + + rc = libxl__ev_xswatch_register(gc, &ds->watch, devstate_watch_callback, + state_path); + if (rc) goto out; + + return 0; + + out: + libxl__ev_devstate_cancel(gc, ds); + return rc; +} + +/* * osevent poll */ diff -r ccc3656225ef -r 0fc994845796 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Jan 27 17:01:24 2012 +0000 +++ b/tools/libxl/libxl_internal.h Fri Jan 27 17:01:25 2012 +0000 @@ -686,6 +686,47 @@ libxl__device_state_handler handler); /* + * libxl__ev_devstate - waits a given time for a device to + * reach a given state. Follows the libxl_ev_* conventions. + * Will generate only one event, and after that is automatically + * cancelled. + */ +typedef struct libxl__ev_devstate libxl__ev_devstate; +typedef void libxl__ev_devstate_callback(libxl__egc *egc, libxl__ev_devstate*, + int rc); + /* rc will be 0, ERROR_TIMEDOUT, ERROR_INVAL (meaning path was removed), + * or ERROR_FAIL if other stuff went wrong (in which latter case, logged) */ + +struct libxl__ev_devstate { + /* read-only for caller, who may read only when waiting: */ + int wanted; + libxl__ev_devstate_callback *callback; + /* as for the remainder, read-only public parts may also be + * read by the caller (notably, watch.path), but only when waiting: */ + libxl__ev_xswatch watch; + libxl__ev_time timeout; +}; + +static inline void libxl__ev_devstate_init(libxl__ev_devstate *ds) +{ + libxl__ev_time_init(&ds->timeout); + libxl__ev_xswatch_init(&ds->watch); +} + +static inline void libxl__ev_devstate_cancel(libxl__gc *gc, + libxl__ev_devstate *ds) +{ + libxl__ev_time_deregister(gc,&ds->timeout); + libxl__ev_xswatch_deregister(gc,&ds->watch); +} + +_hidden int libxl__ev_devstate_wait(libxl__gc *gc, libxl__ev_devstate *ds, + libxl__ev_devstate_callback cb, + const char *state_path, + int state, int milliseconds); + + +/* * libxl__try_phy_backend - Check if there's support for the passed * type of file using the PHY backend * st_mode: mode_t of the file, as returned by stat function _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |