|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 21/29] libxl: cancellation: Make spawns cancellable
The libxl__spawn_spawn internal API permits the caller to specify
.timeout_ms==-1, meaning to wait forever. Provide an explicit
cancellable to allow spawns to be cancelled.
I think there are not currently any internal callers which do use
spawn with an infinite timeout, but this should not be left as a
lacuna for later.
Also, this change means that in practice anything which is cancelled
while spawning ought to be queued for two cancellation notifications:
one from its timeout, and one from the explicit cancellation
registration. Hopefully this will mean that more exciting paths are
exercised during testing.
Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
v2: New in this version of the series.
---
tools/libxl/libxl_exec.c | 17 +++++++++++++++++
tools/libxl/libxl_internal.h | 1 +
2 files changed, 18 insertions(+)
diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c
index 478b4c2..c005b7d 100644
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -261,6 +261,7 @@ static void spawn_watch_event(libxl__egc *egc,
libxl__xswait_state *xswa,
int rc, const char *xsdata);
static void spawn_middle_death(libxl__egc *egc, libxl__ev_child *childw,
pid_t pid, int status);
+static void spawn_cancel(libxl__egc *egc, libxl__ao_cancellable *, int rc);
/* Precondition: Partial. Results: Idle. */
static void spawn_cleanup(libxl__gc *gc, libxl__spawn_state *ss);
@@ -273,6 +274,7 @@ void libxl__spawn_init(libxl__spawn_state *ss)
{
libxl__ev_child_init(&ss->mid);
libxl__xswait_init(&ss->xswait);
+ libxl__ao_cancellable_init(&ss->cancel);
}
int libxl__spawn_spawn(libxl__egc *egc, libxl__spawn_state *ss)
@@ -285,6 +287,10 @@ int libxl__spawn_spawn(libxl__egc *egc, libxl__spawn_state
*ss)
libxl__spawn_init(ss);
ss->failed = ss->detaching = 0;
+ ss->cancel.ao = ao;
+ ss->cancel.callback = spawn_cancel;
+ rc = libxl__ao_cancellable_register(&ss->cancel);
+
ss->xswait.ao = ao;
ss->xswait.what = GCSPRINTF("%s startup", ss->what);
ss->xswait.path = ss->xspath;
@@ -347,6 +353,7 @@ int libxl__spawn_spawn(libxl__egc *egc, libxl__spawn_state
*ss)
static void spawn_cleanup(libxl__gc *gc, libxl__spawn_state *ss)
{
assert(!libxl__ev_child_inuse(&ss->mid));
+ libxl__ao_cancellable_deregister(&ss->cancel);
libxl__xswait_stop(gc, &ss->xswait);
}
@@ -382,6 +389,16 @@ static void spawn_fail(libxl__egc *egc, libxl__spawn_state
*ss)
spawn_detach(gc, ss);
}
+static void spawn_cancel(libxl__egc *egc, libxl__ao_cancellable *cancel,
+ int rc)
+{
+ EGC_GC;
+ libxl__spawn_state *ss = CONTAINER_OF(cancel, *ss, cancel);
+
+ LOG(NOTICE, "%s: spawn cancelled", ss->what);
+ spawn_fail(egc, ss);
+}
+
static void spawn_watch_event(libxl__egc *egc, libxl__xswait_state *xswa,
int rc, const char *p)
{
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 790a489..a251b43 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1418,6 +1418,7 @@ struct libxl__spawn_state {
int detaching; /* we are in Detaching */
int failed; /* might be true whenever we are not Idle */
libxl__ev_child mid; /* always in use whenever we are not Idle */
+ libxl__ao_cancellable cancel; /* in case timeout was -1 */
libxl__xswait_state xswait;
};
--
1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |