All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] libxl: fork/wait handling API proposal
@ 2012-01-31 19:34 Ian Jackson
  0 siblings, 0 replies; only message in thread
From: Ian Jackson @ 2012-01-31 19:34 UTC (permalink / raw)
  To: xen-devel

Here is a first cut of a new API proposal.  There is no implementation
as yet.

libxl will also need to use pthread_atfork to ensure proper tidying up
of things on forks, but this is hidden inside the library and does not
need to be in the API.  I have some WIP code for this but it's not
ready for the light of day.

Ian.

diff --git a/tools/libxl/libxl_event.h b/tools/libxl/libxl_event.h
index f889115..17ffd81 100644
--- a/tools/libxl/libxl_event.h
+++ b/tools/libxl/libxl_event.h
@@ -369,6 +369,125 @@ void libxl_osevent_occurred_fd(libxl_ctx *ctx, void *for_libxl,
  */
 void libxl_osevent_occurred_timeout(libxl_ctx *ctx, void *for_libxl);
 
+
+/*======================================================================*/
+
+/*
+ * Subprocess handling.
+ *
+ * Unfortunately the POSIX interface makes this very awkward.
+ *
+ * There are two possible arrangements for collecting statuses from
+ * wait/waitpid.
+ *
+ * For naive programs:
+ *
+ *     libxl will keep a SIGCHLD handler installed whenever it has an
+ *     active (unreaped) child.  It will reap all children with
+ *     wait(); any children it does not recognise will be passed to
+ *     the application via an optional callback (and will result in
+ *     warnings to stderr if no callback is provided).
+ *
+ *     libxl may have children whenever:
+ *
+ *       - libxl is performing an operation which can be made
+ *         asynchronous; ie one taking a libxl_asyncop_how, even
+ *         if NULL is passed indicating that the operation is
+ *         synchronous; or
+ *
+ *       - events of any kind are being generated, as requested
+ *         by libxl_evenable_....
+ *
+ * For programs which run their own children alongside libxl's:
+ *
+ *     The application must install a SIGCHLD handler and reap (at
+ *     least) all of libxl's children and pass their exit status
+ *     to libxl by calling libxl_childproc_exited.
+ *
+ *     An application which does this must call
+ *     libxl_childproc_setmode.
+ * 
+ * An application which fails to call setmode, or which passes 0 for
+ * hooks, must not:
+ *   - have any child processes running while it uses any libxl
+ *     operation which might create or use child processes (see
+ *     above);
+ *   - install a SIGCHLD handler; or
+ *   - reap any children.
+ */
+
+
+typedef enum {
+    /* libxl owns SIGCHLD whenever it has a child */
+    libxl_sigchld_owner_libxl,
+
+    /* Application promises to call libxl_childproc_exited but
+     * NOT from within a signal handler. */
+    libxl_sigchld_owner_mainloop,
+} libxl_sigchld_owner;
+
+typedef struct {
+    libxl_sigchld_owner chldowner;
+
+    /* All of these are optional: */
+
+    /* Called by libxl instead of fork.  Should behave exactly like
+     * fork, including setting errno etc.  May NOT reenter into libxl.
+     * Application may use this to discover pids of libxl's children,
+     * for example.
+     */
+    pid_t (*fork_replacement)(void *user);
+
+    /* With libxl_sigchld_owner_libxl, called by libxl when it has
+     * reaped a pid.  (Not permitted with _owner_app.)
+     *
+     * Should return 0 if the child was recognised by the application
+     * (or if the application does not keep those kind of records),
+     * ERROR_NOT_READY if the application knows that the child is not
+     * the application's; if it returns another error code it is a
+     * disaster as described for libxl_event_register_callbacks.
+     * (libxl will report unexpected children to its error log.)
+     *
+     * If not supplied, the application is assumed not to start
+     * any children of its own.
+     *
+     * This function is NOT called from within the signal handler.
+     * Rather it will be called from inside a libxl's event handling
+     * code and thus only when libxl is running, for example from
+     * within libxl_event_wait.  (libxl uses the self-pipe trick
+     * to implement this.)
+     *
+     * childproc_exited_callback may call back into libxl, but it
+     * is best to avoid making long-running libxl calls as that might
+     * stall the calling event loop while the nested operation
+     * completes.
+     */
+    int (*childproc_exited_callback)(pid_t, int status, void *user);
+} libxl_childproc_hooks;
+
+/* hooks may be 0 in which is equivalent to &{ libxl_sigchld_owner_libx, 0, 0 }
+ *
+ * May not be called when libxl might have any child processes, or the
+ * behaviour is undefined.  So it is best to call this at
+ * initialisation.
+ */
+void libxl_childproc_setmode(libxl_ctx *ctx, const libxl_childproc_hooks *hooks,
+                             void *user);
+
+/* May be called only by an application which has called setmode with
+ * chldowner == libxl_sigchld_owner_mainloop.  If pid was a process started
+ * by this instance of libxl, returns 0 after doing whatever
+ * processing is appropriate.  Otherwise silently returns
+ * ERROR_NOT_READY.  No other error returns are possible.
+ *
+ * May NOT be called from within a signal handler which might
+ * interrupt any libxl operation.  The application will almost
+ * certainly need to use the self-pipe trick (or a working pselect or
+ * ppoll) to implement this.
+ */
+int libxl_childproc_exited(libxl_ctx *ctx, pid_t, int status);
+
+
 #endif
 
 /*

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-01-31 19:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-31 19:34 [RFC] libxl: fork/wait handling API proposal Ian Jackson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.