|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 01/20] libxl: ao: allow immediate completion
On Fri, 2012-03-16 at 16:26 +0000, Ian Jackson wrote:
> 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>
> ---
> tools/libxl/libxl_event.c | 7 ++++++-
> tools/libxl/libxl_internal.h | 14 ++++++++++----
> 2 files changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
> index 271949a..c89add8 100644
> --- a/tools/libxl/libxl_event.c
> +++ b/tools/libxl/libxl_event.c
> @@ -1225,7 +1225,9 @@ void libxl__ao_complete(libxl__egc *egc, libxl__ao *ao,
> int rc)
>
> 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 *ctx, uint32_t
> domid,
> 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 --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index e0a1070..b1e0588 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -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__egc *egc);
> * 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__egc *egc);
> * 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__egc *egc);
> 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__egc *egc);
> assert(rc); \
> libxl__ao_abort(ao); \
> libxl__ctx_unlock(ao__ctx); /* gc is now invalid */ \
> + EGC_FREE; \
> (rc); \
> })
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |