From 5401f7805580b24f88459d94c901c8f1184877a1 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Fri, 12 May 2017 21:14:11 -0400 Subject: [PATCH] babeltrace(1): handle SIGINT to cancel the graph gracefully MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It goes like this: 1. Ctrl+C 2. SIGINT 3. sigint_handler() 4. Cancel the application's graph. 5. bt_graph_run() eventually returns BT_GRAPH_STATUS_CANCELED or   BT_GRAPH_STATUS_AGAIN. 6. When we get those statuses, we check if the graph is canceled and quit the loop if so. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- cli/babeltrace.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ lib/graph/graph.c | 5 ----- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/cli/babeltrace.c b/cli/babeltrace.c index 03d65891..4f1f8b1f 100644 --- a/cli/babeltrace.c +++ b/cli/babeltrace.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "babeltrace-cfg.h" #include "babeltrace-cfg-cli-args.h" #include "babeltrace-cfg-cli-args-default.h" @@ -58,11 +59,29 @@ #define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH" +/* Application's processing graph (weak) */ +static struct bt_graph *the_graph; +static bool canceled = false; + GPtrArray *loaded_plugins; BT_HIDDEN int bt_cli_log_level = BT_LOG_NONE; +static +void sigint_handler(int signum) +{ + if (signum != SIGINT) { + return; + } + + if (the_graph) { + bt_graph_cancel(the_graph); + } + + canceled = true; +} + static void init_static_data(void) { @@ -1326,6 +1345,7 @@ void cmd_run_ctx_destroy(struct cmd_run_ctx *ctx) } BT_PUT(ctx->graph); + the_graph = NULL; ctx->cfg = NULL; } @@ -1347,6 +1367,7 @@ int cmd_run_ctx_init(struct cmd_run_ctx *ctx, struct bt_config *cfg) goto error; } + the_graph = ctx->graph; ret = bt_graph_add_port_added_listener(ctx->graph, graph_port_added_listener, ctx); if (ret) { @@ -1581,6 +1602,10 @@ int cmd_run(struct bt_config *cfg) goto error; } + if (canceled) { + goto end; + } + BT_LOGI_STR("Running the graph."); /* Run the graph */ @@ -1590,7 +1615,17 @@ int cmd_run(struct bt_config *cfg) switch (graph_status) { case BT_GRAPH_STATUS_OK: break; + case BT_GRAPH_STATUS_CANCELED: + BT_LOGI("Graph was canceled by user: status=%d", + graph_status); + goto error; case BT_GRAPH_STATUS_AGAIN: + if (bt_graph_is_canceled(ctx.graph)) { + BT_LOGI("Graph was canceled by user: status=%d", + graph_status); + goto error; + } + if (cfg->cmd_data.run.retry_duration_us > 0) { BT_LOGV("Got BT_GRAPH_STATUS_AGAIN: sleeping: " "time-us=%" PRIu64, @@ -1678,6 +1713,20 @@ set_level: bt_cli_log_level = log_level; } +void set_sigint_handler(void) +{ + struct sigaction new_action, old_action; + + new_action.sa_handler = sigint_handler; + sigemptyset(&new_action.sa_mask); + new_action.sa_flags = 0; + sigaction(SIGINT, NULL, &old_action); + + if (old_action.sa_handler != SIG_IGN) { + sigaction(SIGINT, &new_action, NULL); + } +} + int main(int argc, const char **argv) { int ret; @@ -1685,6 +1734,7 @@ int main(int argc, const char **argv) struct bt_config *cfg; init_log_level(); + set_sigint_handler(); init_static_data(); cfg = bt_config_cli_args_create_with_default(argc, argv, &retcode); diff --git a/lib/graph/graph.c b/lib/graph/graph.c index 808296f7..ab6b14cf 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -588,11 +588,6 @@ enum bt_graph_status bt_graph_run(struct bt_graph *graph) } do { - if (graph->canceled) { - status = BT_GRAPH_STATUS_CANCELED; - goto end; - } - status = bt_graph_consume(graph); if (status == BT_GRAPH_STATUS_AGAIN) { /* -- 2.34.1