From 9c1ac7b220455f6a58a51517b7bc8bee9364a47c Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 27 Aug 2014 12:03:38 +0300 Subject: [PATCH] compositor: add weston_client_start() weston_client_start() is a new wrapper around weston_client_launch(), that does the process tracking on its own, and logs the process exit status. When users of weston_client_start() want to know when the process exits, they should hook into the wl_client destroy signal. This works for cases where the client is not expected to disconnect without exiting. As wl_client destructor and the sigchld handler run in arbitary order, it is usually difficult for users to maintain both struct weston_process and a struct wl_client pointer. You would need to wait for both destructor and handler to have run, before attempting to respawn the client. This new function relieves the caller from the burden of maintaining the struct weston_process, assuming the caller is only interested in client disconnects. Cc: Boyan Ding Cc: Derek Foreman Signed-off-by: Pekka Paalanen Reviewed-by: Derek Foreman --- src/compositor.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ src/compositor.h | 3 +++ 2 files changed, 63 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index 96e3435f..c62077c4 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -319,6 +319,66 @@ weston_client_launch(struct weston_compositor *compositor, return client; } +struct process_info { + struct weston_process proc; + char *path; +}; + +static void +process_handle_sigchld(struct weston_process *process, int status) +{ + struct process_info *pinfo = + container_of(process, struct process_info, proc); + + /* + * There are no guarantees whether this runs before or after + * the wl_client destructor. + */ + + if (WIFEXITED(status)) { + weston_log("%s exited with status %d\n", pinfo->path, + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + weston_log("%s died on signal %d\n", pinfo->path, + WTERMSIG(status)); + } else { + weston_log("%s disappeared\n", pinfo->path); + } + + free(pinfo->path); + free(pinfo); +} + +WL_EXPORT struct wl_client * +weston_client_start(struct weston_compositor *compositor, const char *path) +{ + struct process_info *pinfo; + struct wl_client *client; + + pinfo = zalloc(sizeof *pinfo); + if (!pinfo) + return NULL; + + pinfo->path = strdup(path); + if (!pinfo->path) + goto out_free; + + client = weston_client_launch(compositor, &pinfo->proc, path, + process_handle_sigchld); + if (!client) + goto out_str; + + return client; + +out_str: + free(pinfo->path); + +out_free: + free(pinfo); + + return NULL; +} + static void region_init_infinite(pixman_region32_t *region) { diff --git a/src/compositor.h b/src/compositor.h index c0fc0a6e..24a97681 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -1345,6 +1345,9 @@ weston_client_launch(struct weston_compositor *compositor, const char *path, weston_process_cleanup_func_t cleanup); +struct wl_client * +weston_client_start(struct weston_compositor *compositor, const char *path); + void weston_watch_process(struct weston_process *process);