Add graph cancellation API
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 11 May 2017 21:54:10 +0000 (17:54 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:42 +0000 (12:57 -0400)
With this API you can cancel a graph with bt_graph_cancel() and
check if a graph is canceled with bt_graph_is_canceled().

A canceled graph is used to indicate to a contained component or
notification iterator if it should retry or not when a system call is
interrupted. This exists mostly to support a clean termination when we
get SIGINT, but with debugger support (a system call is interrupted when
the debugger sends SIGCONT; in this case we need to retry the system
call).

Cancelling a graph also makes bt_graph_run() quit before the next
sink consuming iteration.

It is not allowed to run a canceled graph again. Once it is canceled,
it's dead for good.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/graph/graph-internal.h
include/babeltrace/graph/graph.h
lib/graph/graph.c

index 85c196be6e2bf4793d09da989f7b9b96b80b6307..9efd3590120be49c7e4b767dea5a1767ce3a4042 100644 (file)
@@ -55,6 +55,8 @@ struct bt_graph {
        /* Queue of pointers (weak references) to sink bt_components. */
        GQueue *sinks_to_consume;
 
+       bt_bool canceled;
+
        struct {
                GArray *port_added;
                GArray *port_removed;
index cb14c7daa2c74e6a63dffa93b0f764112bc7a20c..b89aaa82b57d03b28c13318707cc4f78aacfd452 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <babeltrace/graph/component.h>
+#include <babeltrace/types.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -50,6 +51,8 @@ enum bt_graph_status {
        BT_GRAPH_STATUS_NO_SINK = -6,
        /** General error. */
        BT_GRAPH_STATUS_ERROR = -1,
+       /** Canceled. */
+       BT_GRAPH_STATUS_CANCELED = -125,
 };
 
 typedef void (*bt_graph_port_added_listener)(struct bt_port *port,
@@ -114,6 +117,9 @@ extern enum bt_graph_status bt_graph_add_ports_disconnected_listener(
                struct bt_graph *graph,
                bt_graph_ports_disconnected_listener listener, void *data);
 
+extern enum bt_graph_status bt_graph_cancel(struct bt_graph *graph);
+extern bt_bool bt_graph_is_canceled(struct bt_graph *graph);
+
 #ifdef __cplusplus
 }
 #endif
index 8e4dbf68740455950360cd8a590258b71e9fdc93..90eb92fcdd2c0f257dbdd28ab1035da0ec82dcfd 100644 (file)
@@ -163,6 +163,10 @@ struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph,
                goto end;
        }
 
+       if (graph->canceled) {
+               goto end;
+       }
+
        /* Ensure appropriate types for upstream and downstream ports. */
        if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
                goto end;
@@ -357,6 +361,11 @@ enum bt_graph_status bt_graph_add_component_as_sibling(struct bt_graph *graph,
                goto end;
        }
 
+       if (graph->canceled) {
+               status = BT_GRAPH_STATUS_CANCELED;
+               goto end;
+       }
+
        if (bt_component_get_class_type(origin) !=
                        bt_component_get_class_type(new_component)) {
                status = BT_GRAPH_STATUS_INVALID;
@@ -494,6 +503,11 @@ enum bt_graph_status bt_graph_consume(struct bt_graph *graph)
                goto end;
        }
 
+       if (graph->canceled) {
+               status = BT_GRAPH_STATUS_CANCELED;
+               goto end;
+       }
+
        if (g_queue_is_empty(graph->sinks_to_consume)) {
                status = BT_GRAPH_STATUS_END;
                goto end;
@@ -542,21 +556,27 @@ enum bt_graph_status bt_graph_run(struct bt_graph *graph)
 
        if (!graph) {
                status = BT_GRAPH_STATUS_INVALID;
-               goto error;
+               goto end;
        }
 
        do {
+               if (graph->canceled) {
+                       status = BT_GRAPH_STATUS_CANCELED;
+                       goto end;
+               }
+
                status = bt_graph_consume(graph);
                if (status == BT_GRAPH_STATUS_AGAIN) {
                        /*
-                        * If AGAIN is received and there are multiple sinks,
-                        * go ahead and consume from the next sink.
+                        * If AGAIN is received and there are multiple
+                        * sinks, go ahead and consume from the next
+                        * sink.
                         *
-                        * However, in the case where a single sink is left,
-                        * the caller can decide to busy-wait and call
-                        * bt_graph_run continuously until the source is ready
-                        * or it can decide to sleep for an arbitrary amount of
-                        * time.
+                        * However, in the case where a single sink is
+                        * left, the caller can decide to busy-wait and
+                        * call bt_graph_run() continuously until the
+                        * source is ready or it can decide to sleep for
+                        * an arbitrary amount of time.
                         */
                        if (graph->sinks_to_consume->length > 1) {
                                status = BT_GRAPH_STATUS_OK;
@@ -567,7 +587,7 @@ enum bt_graph_status bt_graph_run(struct bt_graph *graph)
        if (g_queue_is_empty(graph->sinks_to_consume)) {
                status = BT_GRAPH_STATUS_END;
        }
-error:
+end:
        return status;
 }
 
@@ -719,3 +739,23 @@ void bt_graph_notify_ports_disconnected(struct bt_graph *graph,
                        downstream_port, listener.data);
        }
 }
+
+extern enum bt_graph_status bt_graph_cancel(struct bt_graph *graph)
+{
+       enum bt_graph_status ret = BT_GRAPH_STATUS_OK;
+
+       if (!graph) {
+               ret = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       graph->canceled = BT_TRUE;
+
+end:
+       return ret;
+}
+
+extern bt_bool bt_graph_is_canceled(struct bt_graph *graph)
+{
+       return graph ? graph->canceled : BT_FALSE;
+}
This page took 0.028004 seconds and 4 git commands to generate.