libxl: ao: cope with fast ao completion with progess events

There are two egcs in an ao initiator: the one in the AO_CREATE
function, and the one in libxl__ao_inprogress.  If synchronous ao
operation generates progress events and completes immediately, the
progress callbacks end up queued in the outer egc.  These callbacks
are currently only called after libxl__ao_inprogress has returned, and
keep the ao alive until they happen.  This is not good because the
principle is that a synchronous ao is not supposed to survive beyond
libxl__ao_inprogress's return.

The fix is to ensure that the callbacks queued in the outer egc are
called early enough that they don't preserve the ao.  This is
straightforward in the AO_INPROGRESS macro because AO_CREATE's egc is
not used inside that macro other than to destroy it.  All we have to
do is destroy it a bit sooner.

This involves unlocking and relocking the ctx since EGC_FREE expects
to be called with the lock released but libxl__ao_inprogress needs it
locked.  This hole in our lock tenure is fine - libxl__ao_inprogress
has such holes already.

It is still possible to use the CTX_LOCK macros for this unlock/lock
because the gc we are using is destroyed only afterwards by
libxl__ao_inprogress.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Ian Jackson committed 2012-10-18 09:35:02 +01:00
1 parent 5622adc372
commit 3f6f3a33d8
1 file changed
+3 -1
+3 -1
View File
@@ -1709,10 +1709,12 @@ _hidden void libxl__egc_cleanup(libxl__egc *egc);
#define AO_INPROGRESS ({ \
libxl_ctx *ao__ctx = libxl__gc_owner(&ao->gc); \
CTX_UNLOCK; \
EGC_FREE; \
CTX_LOCK; \
int ao__rc = libxl__ao_inprogress(ao, \
__FILE__, __LINE__, __func__); \
libxl__ctx_unlock(ao__ctx); /* gc is now invalid */ \
EGC_FREE; \
(ao__rc); \
})
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.