libxl: Introduce libxl__ev_immediate

This new ev allows to arrange a non-reentrant callback to be called.
This happen immediately after the current event is processed and after
other ev_immediates that would have already been registered.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
This commit is contained in:
Anthony PERARD authored and Wei Liu committed 2019-11-18 22:58:48 +00:00
1 parent 66b97659d9
commit f3e4fb552a
2 files changed
+37

No files matched your search

+20
View File
@@ -914,6 +914,15 @@ int libxl__ev_devstate_wait(libxl__ao *ao, libxl__ev_devstate *ds,
return rc;
}
/*
* immediate non-reentrant callback
*/
void libxl__ev_immediate_register(libxl__egc *egc, libxl__ev_immediate *ei)
{
LIBXL_STAILQ_INSERT_TAIL(&egc->ev_immediates, ei, entry);
}
/*
* domain death/destruction
*/
@@ -1395,6 +1404,17 @@ static void egc_run_callbacks(libxl__egc *egc)
EGC_GC;
libxl_event *ev, *ev_tmp;
libxl__aop_occurred *aop, *aop_tmp;
libxl__ev_immediate *ei;
while (!LIBXL_STAILQ_EMPTY(&egc->ev_immediates)) {
ei = LIBXL_STAILQ_FIRST(&egc->ev_immediates);
LIBXL_STAILQ_REMOVE_HEAD(&egc->ev_immediates, entry);
CTX_LOCK;
/* This callback is internal to libxl and expects CTX to be
* locked. */
ei->callback(egc, ei);
CTX_UNLOCK;
}
LIBXL_TAILQ_FOREACH_SAFE(ev, &egc->occurred_for_callback, link, ev_tmp) {
LIBXL_TAILQ_REMOVE(&egc->occurred_for_callback, ev, link);
+17
View File
@@ -200,6 +200,7 @@ typedef struct libxl__ev_slowlock libxl__ev_slowlock;
typedef struct libxl__dm_resume_state libxl__dm_resume_state;
typedef struct libxl__ao_device libxl__ao_device;
typedef struct libxl__multidev libxl__multidev;
typedef struct libxl__ev_immediate libxl__ev_immediate;
typedef struct libxl__domain_create_state libxl__domain_create_state;
typedef void libxl__domain_create_cb(struct libxl__egc *egc,
@@ -363,6 +364,20 @@ struct libxl__ev_child {
LIBXL_LIST_ENTRY(struct libxl__ev_child) entry;
};
/* libxl__ev_immediate
*
* Allow to call a non-reentrant callback.
*
* `callback' will be called immediately as a new event.
*/
struct libxl__ev_immediate {
/* filled by user */
void (*callback)(libxl__egc *, libxl__ev_immediate *);
/* private to libxl__ev_immediate */
LIBXL_STAILQ_ENTRY(libxl__ev_immediate) entry;
};
void libxl__ev_immediate_register(libxl__egc *, libxl__ev_immediate *);
/*
* Lock for device hotplug, qmp_lock.
*
@@ -733,6 +748,7 @@ struct libxl__egc {
struct libxl__event_list occurred_for_callback;
LIBXL_TAILQ_HEAD(, libxl__ao) aos_for_callback;
LIBXL_TAILQ_HEAD(, libxl__aop_occurred) aops_for_callback;
LIBXL_STAILQ_HEAD(, libxl__ev_immediate) ev_immediates;
};
struct libxl__aop_occurred {
@@ -2322,6 +2338,7 @@ _hidden libxl_device_model_version libxl__default_device_model(libxl__gc *gc);
LIBXL_TAILQ_INIT(&(egc).occurred_for_callback); \
LIBXL_TAILQ_INIT(&(egc).aos_for_callback); \
LIBXL_TAILQ_INIT(&(egc).aops_for_callback); \
LIBXL_STAILQ_INIT(&(egc).ev_immediates); \
} while(0)
_hidden void libxl__egc_cleanup(libxl__egc *egc);
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.