From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Jackson Subject: [PATCH 12/14] libxl: ao: Provide manip_refcnt Date: Fri, 20 Dec 2013 18:45:50 +0000 Message-ID: <1387565152-5642-13-git-send-email-ian.jackson@eu.citrix.com> References: <21172.35652.484647.666791@mariner.uk.xensource.com> <1387565152-5642-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: <1387565152-5642-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: Ian Jackson , Ian Campbell List-Id: xen-devel@lists.xenproject.org Previously we used in_initiator to stop the ao being freed while we were still in the initiator function (which would result in the initiator's call to lixl__ao_inprogress accessing the ao after it had been freed). We are going to introduce a new libxl entrypoint which finds, and operates on, ongoing aos. This function needs the same protection, and might even end up running on the same ao multiple times concurrently. So do this with reference counting instead, with a new variable ao->manip_refcnt. We keep ao->in_initiator because that allows us to keep some useful asserts about the sequencing of libxl__ao_inprogress, etc. Signed-off-by: Ian Jackson --- tools/libxl/libxl_event.c | 43 +++++++++++++++++++++++++++++++++--------- tools/libxl/libxl_internal.h | 1 + 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c index 04964c8..d4e5697 100644 --- a/tools/libxl/libxl_event.c +++ b/tools/libxl/libxl_event.c @@ -33,6 +33,8 @@ static libxl__ao *ao_nested_root(libxl__ao *ao); +static void ao__check_destroy(libxl_ctx *ctx, libxl__ao *ao); + /* * The counter osevent_in_hook is used to ensure that the application @@ -1309,8 +1311,7 @@ static void egc_run_callbacks(libxl__egc *egc) ao->how.callback(CTX, ao->rc, ao->how.u.for_callback); CTX_LOCK; ao->notified = 1; - if (!ao->in_initiator) - libxl__ao__destroy(CTX, ao); + ao__check_destroy(CTX, ao); CTX_UNLOCK; } } @@ -1668,6 +1669,33 @@ int libxl_event_wait(libxl_ctx *ctx, libxl_event **event_r, * - destroy the ao */ + +/* + * A "manip" is a libxl public function manipulating this ao, which + * has a pointer to it. We have to not destroy it while that's the + * case, obviously. + */ +static void ao__manip_enter(libxl__ao *ao) +{ + assert(ao->manip_refcnt < INT_MAX); + ao->manip_refcnt++; +} + +static void ao__manip_leave(libxl_ctx *ctx, libxl__ao *ao) +{ + assert(ao->manip_refcnt > 0); + ao->manip_refcnt--; + ao__check_destroy(ctx, ao); +} + +static void ao__check_destroy(libxl_ctx *ctx, libxl__ao *ao) +{ + if (!ao->manip_refcnt && ao->notified) { + assert(ao->complete); + libxl__ao__destroy(ctx,ao); + } +} + void libxl__ao__destroy(libxl_ctx *ctx, libxl__ao *ao) { AO_GC; @@ -1743,8 +1771,8 @@ void libxl__ao_complete_check_progress_reports(libxl__egc *egc, libxl__ao *ao) } ao->notified = 1; } - if (!ao->in_initiator && ao->notified) - libxl__ao__destroy(ctx, ao); + + ao__check_destroy(ctx, ao); } libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid, @@ -1759,6 +1787,7 @@ libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid, ao->magic = LIBXL__AO_MAGIC; ao->constructing = 1; ao->in_initiator = 1; + ao__manip_enter(ao); ao->poller = 0; ao->domid = domid; LIBXL_INIT_GC(ao->gc, ctx); @@ -1839,11 +1868,7 @@ int libxl__ao_inprogress(libxl__ao *ao, } ao->in_initiator = 0; - - if (ao->notified) { - assert(ao->complete); - libxl__ao__destroy(CTX,ao); - } + ao__manip_leave(CTX, ao); return rc; } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index d2f0372..bb239ac 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -444,6 +444,7 @@ struct libxl__ao { */ uint32_t magic; unsigned constructing:1, in_initiator:1, complete:1, notified:1; + int manip_refcnt; libxl__ao *nested_root; int nested_progeny; int progress_reports_outstanding; -- 1.7.10.4