[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.