[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] libxl: ao: allow immediate completion
# HG changeset patch # User Ian Jackson <ian.jackson@xxxxxxxxxxxxx> # Date 1334150048 -3600 # Node ID a0499ee197007b64b1e3379d5f8356abb0c5b045 # Parent d3e4b3ef77834bc879788a450aecc5ada0d41643 libxl: ao: allow immediate completion Make it possible to complete an ao during its initating function. Previously this was not generally possible because initiators did not have an egc. But there is no reason why an ao initiator should not have an egc, so make the standard macros provide one. Change the internal documentation comments accordingly. (This change, which means that an initiator function may call a completion callback directly, is already consistent with the documented external API.) We also invent of a new state flag "constructing" which indicates whether we are between ao__create and ao__inprogress. This is a slightly optimisation which allows ao_complete to not bother poking the wakeup pipe, since the logic in ao__inprogress will not run the event loop if the ao is complete on entry. Also fix the wording in the libxl_internal.h comment forbidding use of ao_how-taking functions from within libxl. (There are sadly currently some such functions.) Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Cc: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Committed-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> --- diff -r d3e4b3ef7783 -r a0499ee19700 tools/libxl/libxl_event.c --- a/tools/libxl/libxl_event.c Wed Apr 11 14:14:07 2012 +0100 +++ b/tools/libxl/libxl_event.c Wed Apr 11 14:14:08 2012 +0100 @@ -1225,7 +1225,9 @@ void libxl__ao_complete(libxl__egc *egc, if (ao->poller) { assert(ao->in_initiator); - libxl__poller_wakeup(egc, ao->poller); + if (!ao->constructing) + /* don't bother with this if we're not in the event loop */ + libxl__poller_wakeup(egc, ao->poller); } else if (ao->how.callback) { LIBXL_TAILQ_INSERT_TAIL(&egc->aos_for_callback, ao, entry_for_callback); } else { @@ -1251,6 +1253,7 @@ libxl__ao *libxl__ao_create(libxl_ctx *c if (!ao) goto out; ao->magic = LIBXL__AO_MAGIC; + ao->constructing = 1; ao->in_initiator = 1; ao->poller = 0; ao->domid = domid; @@ -1275,7 +1278,9 @@ int libxl__ao_inprogress(libxl__ao *ao) int rc; assert(ao->magic == LIBXL__AO_MAGIC); + assert(ao->constructing); assert(ao->in_initiator); + ao->constructing = 0; if (ao->poller) { /* Caller wants it done synchronously. */ diff -r d3e4b3ef7783 -r a0499ee19700 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Wed Apr 11 14:14:07 2012 +0100 +++ b/tools/libxl/libxl_internal.h Wed Apr 11 14:14:08 2012 +0100 @@ -347,7 +347,7 @@ struct libxl__egc { struct libxl__ao { uint32_t magic; - unsigned in_initiator:1, complete:1, notified:1; + unsigned constructing:1, in_initiator:1, complete:1, notified:1; int rc; libxl__gc gc; libxl_asyncop_how how; @@ -1209,7 +1209,11 @@ _hidden void libxl__egc_cleanup(libxl__e * operation ("ao") machinery. The function should take a parameter * const libxl_asyncop_how *ao_how and must start with a call to * AO_INITIATOR_ENTRY. These functions MAY NOT be called from - * outside libxl, because they can cause reentrancy callbacks. + * inside libxl, because they can cause reentrancy callbacks. + * + * For the same reason functions taking an ao_how may make themselves + * an egc with EGC_INIT (and they will generally want to, to be able + * to immediately complete an ao during its setup). * * Lifecycle of an ao: * @@ -1240,8 +1244,7 @@ _hidden void libxl__egc_cleanup(libxl__e * directly or indirectly, should call libxl__ao_complete (with the * ctx locked, as it will generally already be in any event callback * function). This must happen exactly once for each ao (and not if - * the ao has been destroyed, obviously), and it may not happen - * until libxl__ao_inprogress has been called on the ao. + * the ao has been destroyed, obviously). * * - Note that during callback functions, two gcs are available: * - The one in egc, whose lifetime is only this callback @@ -1255,12 +1258,14 @@ _hidden void libxl__egc_cleanup(libxl__e libxl__ctx_lock(ctx); \ libxl__ao *ao = libxl__ao_create(ctx, domid, ao_how); \ if (!ao) { libxl__ctx_unlock(ctx); return ERROR_NOMEM; } \ + libxl__egc egc[1]; LIBXL_INIT_EGC(egc[0],ctx); \ AO_GC; #define AO_INPROGRESS ({ \ libxl_ctx *ao__ctx = libxl__gc_owner(&ao->gc); \ int ao__rc = libxl__ao_inprogress(ao); \ libxl__ctx_unlock(ao__ctx); /* gc is now invalid */ \ + EGC_FREE; \ (ao__rc); \ }) @@ -1269,6 +1274,7 @@ _hidden void libxl__egc_cleanup(libxl__e assert(rc); \ libxl__ao_abort(ao); \ libxl__ctx_unlock(ao__ctx); /* gc is now invalid */ \ + EGC_FREE; \ (rc); \ }) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |