#include <babeltrace/component/component-sink.h>
#include <babeltrace/component/component-filter.h>
#include <babeltrace/component/component-class.h>
-#include <babeltrace/component/component-port.h>
-#include <babeltrace/component/component-graph.h>
-#include <babeltrace/component/component-connection.h>
+#include <babeltrace/component/port.h>
+#include <babeltrace/component/graph.h>
+#include <babeltrace/component/connection.h>
#include <babeltrace/component/notification/iterator.h>
#include <babeltrace/ref.h>
#include <babeltrace/values.h>
babeltrace/component/component-class-source.h \
babeltrace/component/component-class-filter.h \
babeltrace/component/component-class-sink.h \
- babeltrace/component/component-connection.h \
- babeltrace/component/component-port.h \
- babeltrace/component/component-graph.h \
+ babeltrace/component/connection.h \
+ babeltrace/component/port.h \
+ babeltrace/component/graph.h \
babeltrace/component/component-source.h \
babeltrace/component/component-sink.h \
babeltrace/component/component-filter.h
babeltrace/plugin/plugin-python-enabled-internal.h \
babeltrace/plugin/plugin-python-disabled-internal.h \
babeltrace/component/component-class-internal.h \
- babeltrace/component/component-connection-internal.h \
- babeltrace/component/component-port-internal.h \
+ babeltrace/component/connection-internal.h \
+ babeltrace/component/port-internal.h \
babeltrace/component/component-internal.h \
- babeltrace/component/component-graph-internal.h \
+ babeltrace/component/graph-internal.h \
babeltrace/component/component-filter-internal.h \
babeltrace/component/component-sink-internal.h \
babeltrace/component/component-source-internal.h \
+++ /dev/null
-#ifndef BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H
-#define BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H
-
-/*
- * BabelTrace - Component Connection Internal
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component-connection.h>
-#include <babeltrace/object-internal.h>
-
-struct bt_graph;
-
-struct bt_connection {
- /*
- * The graph is a connection's parent and the connection is the parent
- * of all iterators it has created.
- */
- struct bt_object base;
- /*
- * Weak references are held to both ports. Their existence is guaranteed
- * by the existence of the graph and thus, of their respective
- * components.
- */
- /* Downstream port. */
- struct bt_port *input_port;
- /* Upstream port. */
- struct bt_port *output_port;
-};
-
-BT_HIDDEN
-struct bt_connection *bt_connection_create(struct bt_graph *graph,
- struct bt_port *upstream, struct bt_port *downstream);
-
-#endif /* BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_COMPONENT_CONNECTION_H
-#define BABELTRACE_COMPONENT_CONNECTION_H
-
-/*
- * BabelTrace - Babeltrace Component Connection Interface
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_component;
-struct bt_connection;
-
-/* Returns the "downstream" input port. */
-extern struct bt_port *bt_connection_get_input_port(
- struct bt_connection *connection);
-/* Returns the "upstream" output port. */
-extern struct bt_port *bt_connection_get_output_port(
- struct bt_connection *connection);
-
-extern struct bt_notification_iterator *
-bt_connection_create_notification_iterator(struct bt_connection *connection);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_COMPONENT_CONNECTION_H */
+++ /dev/null
-#ifndef BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H
-#define BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H
-
-/*
- * BabelTrace - Component Graph Internal
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component-graph.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <glib.h>
-
-struct bt_graph {
- /**
- * A component graph contains components and point-to-point connection
- * between these components.
- *
- * In terms of ownership:
- * 1) The graph is the components' parent,
- * 2) The graph is the connnections' parent,
- * 3) Components share the ownership of their connections,
- * 4) A connection holds weak references to its two component endpoints.
- */
- struct bt_object base;
-
- /* Array of pointers to bt_connection. */
- GPtrArray *connections;
- /* Array of pointers to bt_component. */
- GPtrArray *components;
- /* Queue of pointers (weak references) to sink bt_components. */
- GQueue *sinks_to_consume;
-};
-
-#endif /* BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_COMPONENT_GRAPH_H
-#define BABELTRACE_COMPONENT_GRAPH_H
-
-/*
- * BabelTrace - Babeltrace Graph Interface
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_port;
-struct bt_connection;
-
-enum bt_graph_status {
- /** Downstream component does not support multiple inputs. */
- BT_GRAPH_STATUS_END = 1,
- BT_GRAPH_STATUS_OK = 0,
- /** Downstream component does not support multiple inputs. */
- BT_GRAPH_STATUS_MULTIPLE_INPUTS_UNSUPPORTED = -1,
- /** Component is already part of another graph. */
- BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH = -2,
- /** Invalid arguments. */
- BT_GRAPH_STATUS_INVALID = -3,
- /** No sink in graph. */
- BT_GRAPH_STATUS_NO_SINK = -4,
- /** General error. */
- BT_GRAPH_STATUS_ERROR = -5,
- /** No sink can consume at the moment. */
- BT_GRAPH_STATUS_AGAIN = -6,
-};
-
-extern struct bt_graph *bt_graph_create(void);
-
-/**
- * Creates a connection between two components using the two ports specified
- * and adds the connection and components (if not already added) to the graph.
- */
-extern struct bt_connection *bt_graph_connect(struct bt_graph *graph,
- struct bt_port *upstream,
- struct bt_port *downstream);
-
-/**
- * Add a component as a "sibling" of the origin component. Sibling share
- * connections equivalent to each other at the time of connection (same
- * upstream and downstream ports).
- */
-extern enum bt_graph_status bt_graph_add_component_as_sibling(
- struct bt_graph *graph, struct bt_component *origin,
- struct bt_component *new_component);
-
-/**
- * Run graph to completion or until a single sink is left and "AGAIN" is received.
- *
- * Runs "bt_component_sink_consume()" on all sinks in round-robin until they all
- * indicate that the end is reached or that an error occured.
- */
-extern enum bt_graph_status bt_graph_run(struct bt_graph *graph,
- enum bt_component_status *component_status);
-
-/**
- * Runs "bt_component_sink_consume()" on the graph's sinks. Each invokation will
- * invoke "bt_component_sink_consume()" on the next sink, in round-robin, until
- * they all indicated that the end is reached.
- */
-extern enum bt_component_status bt_graph_consume(struct bt_graph *graph);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_COMPONENT_GRAPH_H */
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/component/component.h>
#include <babeltrace/component/component-class-internal.h>
-#include <babeltrace/component/component-port-internal.h>
+#include <babeltrace/component/port-internal.h>
#include <babeltrace/object-internal.h>
#include <glib.h>
#include <stdio.h>
+++ /dev/null
-#ifndef BABELTRACE_COMPONENT_PORT_INTERNAL_H
-#define BABELTRACE_COMPONENT_PORT_INTERNAL_H
-
-/*
- * BabelTrace - Babeltrace Component Port
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component-port.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_port {
- struct bt_object base;
- enum bt_port_type type;
- GString *name;
- GPtrArray *connections;
- uint64_t max_connection_count;
-};
-
-BT_HIDDEN
-struct bt_port *bt_port_create(struct bt_component *parent_component,
- enum bt_port_type type, const char *name);
-
-BT_HIDDEN
-int bt_port_add_connection(struct bt_port *port,
- struct bt_connection *connection);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_COMPONENT_PORT_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_COMPONENT_PORT_H
-#define BABELTRACE_COMPONENT_PORT_H
-
-/*
- * BabelTrace - Babeltrace Component Connection Interface
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_port;
-struct bt_connection;
-
-enum bt_port_status {
- BT_PORT_STATUS_OK = 0,
- BT_PORT_STATUS_ERROR = -1,
- BT_PORT_STATUS_INVALID = -2,
-};
-
-enum bt_port_type {
- BT_PORT_TYPE_INPUT = 0,
- BT_PORT_TYPE_OUTPUT = 1,
- BT_PORT_TYPE_UNKOWN = -1,
-};
-
-extern const char *BT_DEFAULT_PORT_NAME;
-
-extern const char *bt_port_get_name(struct bt_port *port);
-extern enum bt_port_type bt_port_get_type(struct bt_port *port);
-
-extern enum bt_port_status bt_port_get_connection_count(struct bt_port *port,
- uint64_t *count);
-extern struct bt_connection *bt_port_get_connection(struct bt_port *port,
- int index);
-
-extern struct bt_component *bt_port_get_component(struct bt_port *port);
-
-/* Only valid before a connection is established. */
-extern enum bt_port_status bt_port_get_maximum_connection_count(
- struct bt_port *port, uint64_t *count);
-extern enum bt_port_status bt_port_set_maximum_connection_count(
- struct bt_port *port, uint64_t count);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_COMPONENT_PORT_H */
--- /dev/null
+#ifndef BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H
+#define BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H
+
+/*
+ * BabelTrace - Component Connection Internal
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/connection.h>
+#include <babeltrace/object-internal.h>
+
+struct bt_graph;
+
+struct bt_connection {
+ /*
+ * The graph is a connection's parent and the connection is the parent
+ * of all iterators it has created.
+ */
+ struct bt_object base;
+ /*
+ * Weak references are held to both ports. Their existence is guaranteed
+ * by the existence of the graph and thus, of their respective
+ * components.
+ */
+ /* Downstream port. */
+ struct bt_port *input_port;
+ /* Upstream port. */
+ struct bt_port *output_port;
+};
+
+BT_HIDDEN
+struct bt_connection *bt_connection_create(struct bt_graph *graph,
+ struct bt_port *upstream, struct bt_port *downstream);
+
+#endif /* BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_COMPONENT_CONNECTION_H
+#define BABELTRACE_COMPONENT_CONNECTION_H
+
+/*
+ * BabelTrace - Babeltrace Component Connection Interface
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_component;
+struct bt_connection;
+
+/* Returns the "downstream" input port. */
+extern struct bt_port *bt_connection_get_input_port(
+ struct bt_connection *connection);
+/* Returns the "upstream" output port. */
+extern struct bt_port *bt_connection_get_output_port(
+ struct bt_connection *connection);
+
+extern struct bt_notification_iterator *
+bt_connection_create_notification_iterator(struct bt_connection *connection);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_COMPONENT_CONNECTION_H */
--- /dev/null
+#ifndef BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H
+#define BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H
+
+/*
+ * BabelTrace - Component Graph Internal
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/graph.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <glib.h>
+
+struct bt_graph {
+ /**
+ * A component graph contains components and point-to-point connection
+ * between these components.
+ *
+ * In terms of ownership:
+ * 1) The graph is the components' parent,
+ * 2) The graph is the connnections' parent,
+ * 3) Components share the ownership of their connections,
+ * 4) A connection holds weak references to its two component endpoints.
+ */
+ struct bt_object base;
+
+ /* Array of pointers to bt_connection. */
+ GPtrArray *connections;
+ /* Array of pointers to bt_component. */
+ GPtrArray *components;
+ /* Queue of pointers (weak references) to sink bt_components. */
+ GQueue *sinks_to_consume;
+};
+
+#endif /* BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_COMPONENT_GRAPH_H
+#define BABELTRACE_COMPONENT_GRAPH_H
+
+/*
+ * BabelTrace - Babeltrace Graph Interface
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/component.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_port;
+struct bt_connection;
+
+enum bt_graph_status {
+ /** Downstream component does not support multiple inputs. */
+ BT_GRAPH_STATUS_END = 1,
+ BT_GRAPH_STATUS_OK = 0,
+ /** Downstream component does not support multiple inputs. */
+ BT_GRAPH_STATUS_MULTIPLE_INPUTS_UNSUPPORTED = -1,
+ /** Component is already part of another graph. */
+ BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH = -2,
+ /** Invalid arguments. */
+ BT_GRAPH_STATUS_INVALID = -3,
+ /** No sink in graph. */
+ BT_GRAPH_STATUS_NO_SINK = -4,
+ /** General error. */
+ BT_GRAPH_STATUS_ERROR = -5,
+ /** No sink can consume at the moment. */
+ BT_GRAPH_STATUS_AGAIN = -6,
+};
+
+extern struct bt_graph *bt_graph_create(void);
+
+/**
+ * Creates a connection between two components using the two ports specified
+ * and adds the connection and components (if not already added) to the graph.
+ */
+extern struct bt_connection *bt_graph_connect(struct bt_graph *graph,
+ struct bt_port *upstream,
+ struct bt_port *downstream);
+
+/**
+ * Add a component as a "sibling" of the origin component. Sibling share
+ * connections equivalent to each other at the time of connection (same
+ * upstream and downstream ports).
+ */
+extern enum bt_graph_status bt_graph_add_component_as_sibling(
+ struct bt_graph *graph, struct bt_component *origin,
+ struct bt_component *new_component);
+
+/**
+ * Run graph to completion or until a single sink is left and "AGAIN" is received.
+ *
+ * Runs "bt_component_sink_consume()" on all sinks in round-robin until they all
+ * indicate that the end is reached or that an error occured.
+ */
+extern enum bt_graph_status bt_graph_run(struct bt_graph *graph,
+ enum bt_component_status *component_status);
+
+/**
+ * Runs "bt_component_sink_consume()" on the graph's sinks. Each invokation will
+ * invoke "bt_component_sink_consume()" on the next sink, in round-robin, until
+ * they all indicated that the end is reached.
+ */
+extern enum bt_component_status bt_graph_consume(struct bt_graph *graph);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_COMPONENT_GRAPH_H */
--- /dev/null
+#ifndef BABELTRACE_COMPONENT_PORT_INTERNAL_H
+#define BABELTRACE_COMPONENT_PORT_INTERNAL_H
+
+/*
+ * BabelTrace - Babeltrace Component Port
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/port.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_port {
+ struct bt_object base;
+ enum bt_port_type type;
+ GString *name;
+ GPtrArray *connections;
+ uint64_t max_connection_count;
+};
+
+BT_HIDDEN
+struct bt_port *bt_port_create(struct bt_component *parent_component,
+ enum bt_port_type type, const char *name);
+
+BT_HIDDEN
+int bt_port_add_connection(struct bt_port *port,
+ struct bt_connection *connection);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_COMPONENT_PORT_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_COMPONENT_PORT_H
+#define BABELTRACE_COMPONENT_PORT_H
+
+/*
+ * BabelTrace - Babeltrace Component Connection Interface
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_port;
+struct bt_connection;
+
+enum bt_port_status {
+ BT_PORT_STATUS_OK = 0,
+ BT_PORT_STATUS_ERROR = -1,
+ BT_PORT_STATUS_INVALID = -2,
+};
+
+enum bt_port_type {
+ BT_PORT_TYPE_INPUT = 0,
+ BT_PORT_TYPE_OUTPUT = 1,
+ BT_PORT_TYPE_UNKOWN = -1,
+};
+
+extern const char *BT_DEFAULT_PORT_NAME;
+
+extern const char *bt_port_get_name(struct bt_port *port);
+extern enum bt_port_type bt_port_get_type(struct bt_port *port);
+
+extern enum bt_port_status bt_port_get_connection_count(struct bt_port *port,
+ uint64_t *count);
+extern struct bt_connection *bt_port_get_connection(struct bt_port *port,
+ int index);
+
+extern struct bt_component *bt_port_get_component(struct bt_port *port);
+
+/* Only valid before a connection is established. */
+extern enum bt_port_status bt_port_get_maximum_connection_count(
+ struct bt_port *port, uint64_t *count);
+extern enum bt_port_status bt_port_set_maximum_connection_count(
+ struct bt_port *port, uint64_t count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_COMPONENT_PORT_H */
libcomponent_la_SOURCES = \
component.c \
component-class.c \
- component-graph.c \
- component-connection.c \
- component-port.c \
+ graph.c \
+ connection.c \
+ port.c \
source.c \
sink.c \
filter.c \
+++ /dev/null
-/*
- * component-connection.c
- *
- * Babeltrace Connection
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component-connection-internal.h>
-#include <babeltrace/component/component-graph-internal.h>
-#include <babeltrace/component/component-port-internal.h>
-#include <babeltrace/component/component-source-internal.h>
-#include <babeltrace/component/component-filter-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler.h>
-#include <glib.h>
-
-static
-void bt_connection_destroy(struct bt_object *obj)
-{
- struct bt_connection *connection = container_of(obj,
- struct bt_connection, base);
-
- /*
- * No bt_put on ports as a connection only holds _weak_ references
- * to them.
- */
- g_free(connection);
-}
-
-BT_HIDDEN
-struct bt_connection *bt_connection_create(
- struct bt_graph *graph,
- struct bt_port *upstream, struct bt_port *downstream)
-{
- struct bt_connection *connection = NULL;
-
- if (bt_port_get_type(upstream) != BT_PORT_TYPE_OUTPUT) {
- goto end;
- }
- if (bt_port_get_type(downstream) != BT_PORT_TYPE_INPUT) {
- goto end;
- }
-
- connection = g_new0(struct bt_connection, 1);
- if (!connection) {
- goto end;
- }
-
- bt_object_init(connection, bt_connection_destroy);
- /* Weak references are taken, see comment in header. */
- connection->output_port = upstream;
- connection->input_port = downstream;
- bt_port_add_connection(upstream, connection);
- bt_port_add_connection(downstream, connection);
- bt_object_set_parent(connection, &graph->base);
-end:
- return connection;
-}
-
-struct bt_port *bt_connection_get_input_port(
- struct bt_connection *connection)
-{
- return connection ? connection->input_port : NULL;
-}
-
-struct bt_port *bt_connection_get_output_port(
- struct bt_connection *connection)
-{
- return connection ? connection->output_port : NULL;
-}
-
-struct bt_notification_iterator *
-bt_connection_create_notification_iterator(struct bt_connection *connection)
-{
- struct bt_component *upstream_component = NULL;
- struct bt_notification_iterator *it = NULL;
-
- if (!connection) {
- goto end;
- }
-
- upstream_component = bt_port_get_component(connection->output_port);
- assert(upstream_component);
-
- switch (bt_component_get_class_type(upstream_component)) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- it = bt_component_source_create_notification_iterator(
- upstream_component);
- break;
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- it = bt_component_filter_create_notification_iterator(
- upstream_component);
- break;
- default:
- goto end;
- }
-end:
- bt_put(upstream_component);
- return it;
-}
+++ /dev/null
-/*
- * component-graph.c
- *
- * Babeltrace Plugin Component Graph
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component-internal.h>
-#include <babeltrace/component/component-graph-internal.h>
-#include <babeltrace/component/component-connection-internal.h>
-#include <babeltrace/component/component-sink-internal.h>
-#include <babeltrace/component/component-source.h>
-#include <babeltrace/component/component-filter.h>
-#include <babeltrace/component/component-port.h>
-#include <babeltrace/compiler.h>
-#include <unistd.h>
-
-static
-void bt_graph_destroy(struct bt_object *obj)
-{
- struct bt_graph *graph = container_of(obj,
- struct bt_graph, base);
-
- if (graph->components) {
- g_ptr_array_free(graph->components, TRUE);
- }
- if (graph->connections) {
- g_ptr_array_free(graph->connections, TRUE);
- }
- if (graph->sinks_to_consume) {
- g_queue_free(graph->sinks_to_consume);
- }
- g_free(graph);
-}
-
-struct bt_graph *bt_graph_create(void)
-{
- struct bt_graph *graph;
-
- graph = g_new0(struct bt_graph, 1);
- if (!graph) {
- goto end;
- }
-
- bt_object_init(graph, bt_graph_destroy);
-
- graph->connections = g_ptr_array_new_with_free_func(bt_object_release);
- if (!graph->connections) {
- goto error;
- }
- graph->components = g_ptr_array_new_with_free_func(bt_object_release);
- if (!graph->components) {
- goto error;
- }
- graph->sinks_to_consume = g_queue_new();
- if (!graph->sinks_to_consume) {
- goto error;
- }
-end:
- return graph;
-error:
- BT_PUT(graph);
- goto end;
-}
-
-struct bt_connection *bt_graph_connect(struct bt_graph *graph,
- struct bt_port *upstream_port,
- struct bt_port *downstream_port)
-{
- struct bt_connection *connection = NULL;
- struct bt_graph *upstream_graph = NULL;
- struct bt_graph *downstream_graph = NULL;
- struct bt_component *upstream_component = NULL;
- struct bt_component *downstream_component = NULL;
- enum bt_component_status component_status;
- bool components_added = false;
-
- if (!graph || !upstream_port || !downstream_port) {
- goto end;
- }
-
- if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
- goto end;
- }
- if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
- goto end;
- }
-
- /* Ensure the components are not already part of another graph. */
- upstream_component = bt_port_get_component(upstream_port);
- assert(upstream_component);
- upstream_graph = bt_component_get_graph(upstream_component);
- if (upstream_graph && (graph != upstream_graph)) {
- fprintf(stderr, "Upstream component is already part of another graph\n");
- goto error;
- }
-
- downstream_component = bt_port_get_component(downstream_port);
- assert(downstream_component);
- downstream_graph = bt_component_get_graph(downstream_component);
- if (downstream_graph && (graph != downstream_graph)) {
- fprintf(stderr, "Downstream component is already part of another graph\n");
- goto error;
- }
-
- connection = bt_connection_create(graph, upstream_port,
- downstream_port);
- if (!connection) {
- goto error;
- }
-
- /*
- * Ownership of up/downstream_component and of the connection object is
- * transferred to the graph.
- */
- g_ptr_array_add(graph->connections, connection);
- g_ptr_array_add(graph->components, upstream_component);
- g_ptr_array_add(graph->components, downstream_component);
- if (bt_component_get_class_type(downstream_component) ==
- BT_COMPONENT_CLASS_TYPE_SINK) {
- g_queue_push_tail(graph->sinks_to_consume,
- downstream_component);
- }
-
- /*
- * The graph is now the parent of these components which garantees their
- * existence for the duration of the graph's lifetime.
- */
- bt_component_set_graph(upstream_component, graph);
- bt_put(upstream_component);
- bt_component_set_graph(downstream_component, graph);
- bt_put(downstream_component);
-
- /* Rollback the connection from this point on. */
- components_added = true;
-
- /*
- * The components and connection are added to the graph before invoking
- * the new_connection method in order to make them visible to the
- * components during the method's invocation.
- */
- component_status = bt_component_new_connection(upstream_component,
- upstream_port, connection);
- if (component_status != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
- component_status = bt_component_new_connection(downstream_component,
- downstream_port, connection);
- if (component_status != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-end:
- bt_put(upstream_graph);
- bt_put(downstream_graph);
- return connection;
-error:
- if (components_added) {
- if (bt_component_get_class_type(downstream_component) ==
- BT_COMPONENT_CLASS_TYPE_SINK) {
- g_queue_pop_tail(graph->sinks_to_consume);
- }
- g_ptr_array_set_size(graph->connections,
- graph->connections->len - 1);
- g_ptr_array_set_size(graph->components,
- graph->components->len - 2);
- }
- goto end;
-}
-
-static
-int get_component_port_counts(struct bt_component *component, int *input_count,
- int *output_count)
-{
- int ret = -1;
-
- switch (bt_component_get_class_type(component)) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- ret = bt_component_source_get_output_port_count(component);
- if (ret < 0) {
- goto end;
- }
- *output_count = ret;
- break;
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- ret = bt_component_filter_get_output_port_count(component);
- if (ret < 0) {
- goto end;
- }
- *output_count = ret;
- break;
- ret = bt_component_filter_get_input_port_count(component);
- if (ret < 0) {
- goto end;
- }
- *input_count = ret;
- break;
- case BT_COMPONENT_CLASS_TYPE_SINK:
- ret = bt_component_sink_get_input_port_count(component);
- if (ret < 0) {
- goto end;
- }
- *input_count = ret;
- break;
- default:
- assert(false);
- break;
- }
- ret = 0;
-end:
- return ret;
-}
-
-static
-struct bt_port *get_input_port(struct bt_component *component, int index)
-{
- struct bt_port *port = NULL;
-
- switch (bt_component_get_class_type(component)) {
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- port = bt_component_filter_get_input_port_at_index(component,
- index);
- break;
- case BT_COMPONENT_CLASS_TYPE_SINK:
- port = bt_component_sink_get_input_port_at_index(component,
- index);
- break;
- default:
- assert(false);
- }
- return port;
-}
-
-static
-struct bt_port *get_output_port(struct bt_component *component, int index)
-{
- struct bt_port *port = NULL;
-
- switch (bt_component_get_class_type(component)) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- port = bt_component_source_get_output_port_at_index(component,
- index);
- break;
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- port = bt_component_filter_get_output_port_at_index(component,
- index);
- break;
- default:
- assert(false);
- }
- return port;
-}
-
-enum bt_graph_status bt_graph_add_component_as_sibling(struct bt_graph *graph,
- struct bt_component *origin,
- struct bt_component *new_component)
-{
- int origin_input_port_count = 0;
- int origin_output_port_count = 0;
- int new_input_port_count = 0;
- int new_output_port_count = 0;
- enum bt_graph_status status = BT_GRAPH_STATUS_OK;
- struct bt_graph *origin_graph = NULL;
- struct bt_graph *new_graph = NULL;
- struct bt_port *origin_port = NULL;
- struct bt_port *new_port = NULL;
- struct bt_port *upstream_port = NULL;
- struct bt_port *downstream_port = NULL;
- struct bt_connection *origin_connection = NULL;
- struct bt_connection *new_connection = NULL;
- int port_index;
-
- if (!graph || !origin || !new_component) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- if (bt_component_get_class_type(origin) !=
- bt_component_get_class_type(new_component)) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- origin_graph = bt_component_get_graph(origin);
- if (!origin_graph || (origin_graph != graph)) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- new_graph = bt_component_get_graph(new_component);
- if (new_graph) {
- status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
- goto end;
- }
-
- if (get_component_port_counts(origin, &origin_input_port_count,
- &origin_output_port_count)) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
- if (get_component_port_counts(new_component, &new_input_port_count,
- &new_output_port_count)) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- if (origin_input_port_count != new_input_port_count ||
- origin_output_port_count != new_output_port_count) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- /* Replicate input connections. */
- for (port_index = 0; port_index< origin_input_port_count; port_index++) {
- uint64_t connection_count, connection_index;
-
- origin_port = get_input_port(origin, port_index);
- if (!origin_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
- new_port = get_input_port(new_component, port_index);
- if (!new_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- if (bt_port_get_connection_count(origin_port, &connection_count) !=
- BT_PORT_STATUS_OK) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- for (connection_index = 0; connection_index < connection_count;
- connection_index++) {
- origin_connection = bt_port_get_connection(origin_port,
- connection_index);
- if (!origin_connection) {
- goto error_disconnect;
- }
-
- upstream_port = bt_connection_get_output_port(
- origin_connection);
- if (!upstream_port) {
- goto error_disconnect;
- }
-
- new_connection = bt_graph_connect(graph, upstream_port,
- new_port);
- if (!new_connection) {
- goto error_disconnect;
- }
-
- BT_PUT(upstream_port);
- BT_PUT(origin_connection);
- BT_PUT(new_connection);
- }
- BT_PUT(origin_port);
- BT_PUT(new_port);
- }
-
- /* Replicate output connections. */
- for (port_index = 0; port_index< origin_output_port_count; port_index++) {
- uint64_t connection_count, connection_index;
-
- origin_port = get_output_port(origin, port_index);
- if (!origin_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
- new_port = get_output_port(new_component, port_index);
- if (!new_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- if (bt_port_get_connection_count(origin_port, &connection_count) !=
- BT_PORT_STATUS_OK) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- for (connection_index = 0; connection_index < connection_count;
- connection_index++) {
- origin_connection = bt_port_get_connection(origin_port,
- connection_index);
- if (!origin_connection) {
- goto error_disconnect;
- }
-
- downstream_port = bt_connection_get_input_port(
- origin_connection);
- if (!downstream_port) {
- goto error_disconnect;
- }
-
- new_connection = bt_graph_connect(graph, new_port,
- downstream_port);
- if (!new_connection) {
- goto error_disconnect;
- }
-
- BT_PUT(downstream_port);
- BT_PUT(origin_connection);
- BT_PUT(new_connection);
- }
- BT_PUT(origin_port);
- BT_PUT(new_port);
- }
-end:
- bt_put(origin_graph);
- bt_put(new_graph);
- bt_put(origin_port);
- bt_put(new_port);
- bt_put(upstream_port);
- bt_put(downstream_port);
- bt_put(origin_connection);
- bt_put(new_connection);
- return status;
-error_disconnect:
- /* Destroy all connections of the new component. */
- /* FIXME. */
- goto end;
-}
-
-enum bt_component_status bt_graph_consume(struct bt_graph *graph)
-{
- struct bt_component *sink;
- enum bt_component_status status;
- GList *current_node;
-
- if (!graph) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- if (g_queue_is_empty(graph->sinks_to_consume)) {
- status = BT_COMPONENT_STATUS_END;
- goto end;
- }
-
- current_node = g_queue_pop_head_link(graph->sinks_to_consume);
- sink = current_node->data;
- status = bt_component_sink_consume(sink);
- if (status != BT_COMPONENT_STATUS_END) {
- g_queue_push_tail_link(graph->sinks_to_consume, current_node);
- goto end;
- }
-
- /* End reached, the node is not added back to the queue and free'd. */
- g_queue_delete_link(graph->sinks_to_consume, current_node);
-
- /* Don't forward an END status if there are sinks left to consume. */
- if (!g_queue_is_empty(graph->sinks_to_consume)) {
- status = BT_GRAPH_STATUS_OK;
- goto end;
- }
-end:
- return status;
-}
-
-enum bt_graph_status bt_graph_run(struct bt_graph *graph,
- enum bt_component_status *_component_status)
-{
- enum bt_component_status component_status;
- enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
-
- if (!graph) {
- graph_status = BT_GRAPH_STATUS_INVALID;
- goto error;
- }
-
- do {
- component_status = bt_graph_consume(graph);
- if (component_status == BT_COMPONENT_STATUS_AGAIN) {
- /*
- * 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.
- */
- if (graph->sinks_to_consume->length > 1) {
- component_status = BT_COMPONENT_STATUS_OK;
- }
- }
- } while (component_status == BT_COMPONENT_STATUS_OK);
-
- if (_component_status) {
- *_component_status = component_status;
- }
-
- if (g_queue_is_empty(graph->sinks_to_consume)) {
- graph_status = BT_GRAPH_STATUS_END;
- } else if (component_status == BT_COMPONENT_STATUS_AGAIN) {
- graph_status = BT_GRAPH_STATUS_AGAIN;
- } else {
- graph_status = BT_GRAPH_STATUS_ERROR;
- }
-error:
- return graph_status;
-}
+++ /dev/null
-/*
- * component-port.c
- *
- * Babeltrace Port
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/component/component-internal.h>
-#include <babeltrace/component/component-port-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler.h>
-
-static
-void bt_port_destroy(struct bt_object *obj)
-{
- struct bt_port *port = container_of(obj, struct bt_port, base);
-
- if (port->name) {
- g_string_free(port->name, TRUE);
- }
- if (port->connections) {
- g_ptr_array_free(port->connections, TRUE);
- }
- g_free(port);
-}
-
-BT_HIDDEN
-struct bt_port *bt_port_create(struct bt_component *parent_component,
- enum bt_port_type type, const char *name)
-{
- struct bt_port *port;
-
- assert(name);
- assert(parent_component);
- assert(type == BT_PORT_TYPE_INPUT || type == BT_PORT_TYPE_OUTPUT);
-
- if (*name == '\0') {
- port = NULL;
- goto end;
- }
-
- port = g_new0(struct bt_port, 1);
- if (!port) {
- goto end;
- }
-
- bt_object_init(port, bt_port_destroy);
- port->name = g_string_new(name);
- if (!port->name) {
- BT_PUT(port);
- goto end;
- }
-
- port->type = type;
- port->connections = g_ptr_array_new();
- if (!port->connections) {
- BT_PUT(port);
- goto end;
- }
-
- port->max_connection_count = 1;
-
- bt_object_set_parent(port, &parent_component->base);
-end:
- return port;
-}
-
-const char *bt_port_get_name(struct bt_port *port)
-{
- return port ? port->name->str : NULL;
-}
-
-enum bt_port_type bt_port_get_type(struct bt_port *port)
-{
- return port ? port->type : BT_PORT_TYPE_UNKOWN;
-}
-
-enum bt_port_status bt_port_get_connection_count(struct bt_port *port,
- uint64_t *count)
-{
- enum bt_port_status status = BT_PORT_STATUS_OK;
-
- if (!port || !count) {
- status = BT_PORT_STATUS_INVALID;
- goto end;
- }
-
- *count = (uint64_t) port->connections->len;
-end:
- return status;
-}
-
-struct bt_connection *bt_port_get_connection(struct bt_port *port, int index)
-{
- struct bt_connection *connection;
-
- if (!port || index < 0 || index >= port->connections->len) {
- connection = NULL;
- goto end;
- }
-
- connection = bt_get(g_ptr_array_index(port->connections, index));
-end:
- return connection;
-}
-
-struct bt_component *bt_port_get_component(struct bt_port *port)
-{
- return (struct bt_component *) bt_object_get_parent(port);
-}
-
-BT_HIDDEN
-int bt_port_add_connection(struct bt_port *port,
- struct bt_connection *connection)
-{
- int ret = 0;
-
- if (port->connections->len == port->max_connection_count) {
- ret = -1;
- goto end;
- }
-
- /*
- * Don't take a reference on connection as its existence is guaranteed
- * by the existence of the graph in which the connection exists.
- */
- g_ptr_array_add(port->connections, connection);
-end:
- return ret;
-}
-
-enum bt_port_status bt_port_get_maximum_connection_count(
- struct bt_port *port, uint64_t *count)
-{
- enum bt_port_status status = BT_PORT_STATUS_OK;
-
- if (!port || !count) {
- status = BT_PORT_STATUS_INVALID;
- goto end;
- }
-
- *count = port->max_connection_count;
-end:
- return status;
-}
-
-enum bt_port_status bt_port_set_maximum_connection_count(
- struct bt_port *port, uint64_t count)
-{
- enum bt_port_status status = BT_PORT_STATUS_OK;
-
- if (!port || count < port->connections->len || count == 0) {
- status = BT_PORT_STATUS_INVALID;
- goto end;
- }
-
- port->max_connection_count = count;
-end:
- return status;
-}
#include <babeltrace/component/component-source-internal.h>
#include <babeltrace/component/component-filter-internal.h>
#include <babeltrace/component/component-sink-internal.h>
-#include <babeltrace/component/component-graph-internal.h>
+#include <babeltrace/component/graph-internal.h>
#include <babeltrace/component/notification/iterator-internal.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/compiler.h>
--- /dev/null
+/*
+ * connection.c
+ *
+ * Babeltrace Connection
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/connection-internal.h>
+#include <babeltrace/component/graph-internal.h>
+#include <babeltrace/component/port-internal.h>
+#include <babeltrace/component/component-source-internal.h>
+#include <babeltrace/component/component-filter-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler.h>
+#include <glib.h>
+
+static
+void bt_connection_destroy(struct bt_object *obj)
+{
+ struct bt_connection *connection = container_of(obj,
+ struct bt_connection, base);
+
+ /*
+ * No bt_put on ports as a connection only holds _weak_ references
+ * to them.
+ */
+ g_free(connection);
+}
+
+BT_HIDDEN
+struct bt_connection *bt_connection_create(
+ struct bt_graph *graph,
+ struct bt_port *upstream, struct bt_port *downstream)
+{
+ struct bt_connection *connection = NULL;
+
+ if (bt_port_get_type(upstream) != BT_PORT_TYPE_OUTPUT) {
+ goto end;
+ }
+ if (bt_port_get_type(downstream) != BT_PORT_TYPE_INPUT) {
+ goto end;
+ }
+
+ connection = g_new0(struct bt_connection, 1);
+ if (!connection) {
+ goto end;
+ }
+
+ bt_object_init(connection, bt_connection_destroy);
+ /* Weak references are taken, see comment in header. */
+ connection->output_port = upstream;
+ connection->input_port = downstream;
+ bt_port_add_connection(upstream, connection);
+ bt_port_add_connection(downstream, connection);
+ bt_object_set_parent(connection, &graph->base);
+end:
+ return connection;
+}
+
+struct bt_port *bt_connection_get_input_port(
+ struct bt_connection *connection)
+{
+ return connection ? connection->input_port : NULL;
+}
+
+struct bt_port *bt_connection_get_output_port(
+ struct bt_connection *connection)
+{
+ return connection ? connection->output_port : NULL;
+}
+
+struct bt_notification_iterator *
+bt_connection_create_notification_iterator(struct bt_connection *connection)
+{
+ struct bt_component *upstream_component = NULL;
+ struct bt_notification_iterator *it = NULL;
+
+ if (!connection) {
+ goto end;
+ }
+
+ upstream_component = bt_port_get_component(connection->output_port);
+ assert(upstream_component);
+
+ switch (bt_component_get_class_type(upstream_component)) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ it = bt_component_source_create_notification_iterator(
+ upstream_component);
+ break;
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ it = bt_component_filter_create_notification_iterator(
+ upstream_component);
+ break;
+ default:
+ goto end;
+ }
+end:
+ bt_put(upstream_component);
+ return it;
+}
--- /dev/null
+/*
+ * graph.c
+ *
+ * Babeltrace Plugin Component Graph
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/component-internal.h>
+#include <babeltrace/component/graph-internal.h>
+#include <babeltrace/component/connection-internal.h>
+#include <babeltrace/component/component-sink-internal.h>
+#include <babeltrace/component/component-source.h>
+#include <babeltrace/component/component-filter.h>
+#include <babeltrace/component/port.h>
+#include <babeltrace/compiler.h>
+#include <unistd.h>
+
+static
+void bt_graph_destroy(struct bt_object *obj)
+{
+ struct bt_graph *graph = container_of(obj,
+ struct bt_graph, base);
+
+ if (graph->components) {
+ g_ptr_array_free(graph->components, TRUE);
+ }
+ if (graph->connections) {
+ g_ptr_array_free(graph->connections, TRUE);
+ }
+ if (graph->sinks_to_consume) {
+ g_queue_free(graph->sinks_to_consume);
+ }
+ g_free(graph);
+}
+
+struct bt_graph *bt_graph_create(void)
+{
+ struct bt_graph *graph;
+
+ graph = g_new0(struct bt_graph, 1);
+ if (!graph) {
+ goto end;
+ }
+
+ bt_object_init(graph, bt_graph_destroy);
+
+ graph->connections = g_ptr_array_new_with_free_func(bt_object_release);
+ if (!graph->connections) {
+ goto error;
+ }
+ graph->components = g_ptr_array_new_with_free_func(bt_object_release);
+ if (!graph->components) {
+ goto error;
+ }
+ graph->sinks_to_consume = g_queue_new();
+ if (!graph->sinks_to_consume) {
+ goto error;
+ }
+end:
+ return graph;
+error:
+ BT_PUT(graph);
+ goto end;
+}
+
+struct bt_connection *bt_graph_connect(struct bt_graph *graph,
+ struct bt_port *upstream_port,
+ struct bt_port *downstream_port)
+{
+ struct bt_connection *connection = NULL;
+ struct bt_graph *upstream_graph = NULL;
+ struct bt_graph *downstream_graph = NULL;
+ struct bt_component *upstream_component = NULL;
+ struct bt_component *downstream_component = NULL;
+ enum bt_component_status component_status;
+ bool components_added = false;
+
+ if (!graph || !upstream_port || !downstream_port) {
+ goto end;
+ }
+
+ if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
+ goto end;
+ }
+ if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
+ goto end;
+ }
+
+ /* Ensure the components are not already part of another graph. */
+ upstream_component = bt_port_get_component(upstream_port);
+ assert(upstream_component);
+ upstream_graph = bt_component_get_graph(upstream_component);
+ if (upstream_graph && (graph != upstream_graph)) {
+ fprintf(stderr, "Upstream component is already part of another graph\n");
+ goto error;
+ }
+
+ downstream_component = bt_port_get_component(downstream_port);
+ assert(downstream_component);
+ downstream_graph = bt_component_get_graph(downstream_component);
+ if (downstream_graph && (graph != downstream_graph)) {
+ fprintf(stderr, "Downstream component is already part of another graph\n");
+ goto error;
+ }
+
+ connection = bt_connection_create(graph, upstream_port,
+ downstream_port);
+ if (!connection) {
+ goto error;
+ }
+
+ /*
+ * Ownership of up/downstream_component and of the connection object is
+ * transferred to the graph.
+ */
+ g_ptr_array_add(graph->connections, connection);
+ g_ptr_array_add(graph->components, upstream_component);
+ g_ptr_array_add(graph->components, downstream_component);
+ if (bt_component_get_class_type(downstream_component) ==
+ BT_COMPONENT_CLASS_TYPE_SINK) {
+ g_queue_push_tail(graph->sinks_to_consume,
+ downstream_component);
+ }
+
+ /*
+ * The graph is now the parent of these components which garantees their
+ * existence for the duration of the graph's lifetime.
+ */
+ bt_component_set_graph(upstream_component, graph);
+ bt_put(upstream_component);
+ bt_component_set_graph(downstream_component, graph);
+ bt_put(downstream_component);
+
+ /* Rollback the connection from this point on. */
+ components_added = true;
+
+ /*
+ * The components and connection are added to the graph before invoking
+ * the new_connection method in order to make them visible to the
+ * components during the method's invocation.
+ */
+ component_status = bt_component_new_connection(upstream_component,
+ upstream_port, connection);
+ if (component_status != BT_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+ component_status = bt_component_new_connection(downstream_component,
+ downstream_port, connection);
+ if (component_status != BT_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+end:
+ bt_put(upstream_graph);
+ bt_put(downstream_graph);
+ return connection;
+error:
+ if (components_added) {
+ if (bt_component_get_class_type(downstream_component) ==
+ BT_COMPONENT_CLASS_TYPE_SINK) {
+ g_queue_pop_tail(graph->sinks_to_consume);
+ }
+ g_ptr_array_set_size(graph->connections,
+ graph->connections->len - 1);
+ g_ptr_array_set_size(graph->components,
+ graph->components->len - 2);
+ }
+ goto end;
+}
+
+static
+int get_component_port_counts(struct bt_component *component, int *input_count,
+ int *output_count)
+{
+ int ret = -1;
+
+ switch (bt_component_get_class_type(component)) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ ret = bt_component_source_get_output_port_count(component);
+ if (ret < 0) {
+ goto end;
+ }
+ *output_count = ret;
+ break;
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ ret = bt_component_filter_get_output_port_count(component);
+ if (ret < 0) {
+ goto end;
+ }
+ *output_count = ret;
+ break;
+ ret = bt_component_filter_get_input_port_count(component);
+ if (ret < 0) {
+ goto end;
+ }
+ *input_count = ret;
+ break;
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ ret = bt_component_sink_get_input_port_count(component);
+ if (ret < 0) {
+ goto end;
+ }
+ *input_count = ret;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ ret = 0;
+end:
+ return ret;
+}
+
+static
+struct bt_port *get_input_port(struct bt_component *component, int index)
+{
+ struct bt_port *port = NULL;
+
+ switch (bt_component_get_class_type(component)) {
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ port = bt_component_filter_get_input_port_at_index(component,
+ index);
+ break;
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ port = bt_component_sink_get_input_port_at_index(component,
+ index);
+ break;
+ default:
+ assert(false);
+ }
+ return port;
+}
+
+static
+struct bt_port *get_output_port(struct bt_component *component, int index)
+{
+ struct bt_port *port = NULL;
+
+ switch (bt_component_get_class_type(component)) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ port = bt_component_source_get_output_port_at_index(component,
+ index);
+ break;
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ port = bt_component_filter_get_output_port_at_index(component,
+ index);
+ break;
+ default:
+ assert(false);
+ }
+ return port;
+}
+
+enum bt_graph_status bt_graph_add_component_as_sibling(struct bt_graph *graph,
+ struct bt_component *origin,
+ struct bt_component *new_component)
+{
+ int origin_input_port_count = 0;
+ int origin_output_port_count = 0;
+ int new_input_port_count = 0;
+ int new_output_port_count = 0;
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+ struct bt_graph *origin_graph = NULL;
+ struct bt_graph *new_graph = NULL;
+ struct bt_port *origin_port = NULL;
+ struct bt_port *new_port = NULL;
+ struct bt_port *upstream_port = NULL;
+ struct bt_port *downstream_port = NULL;
+ struct bt_connection *origin_connection = NULL;
+ struct bt_connection *new_connection = NULL;
+ int port_index;
+
+ if (!graph || !origin || !new_component) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ if (bt_component_get_class_type(origin) !=
+ bt_component_get_class_type(new_component)) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ origin_graph = bt_component_get_graph(origin);
+ if (!origin_graph || (origin_graph != graph)) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ new_graph = bt_component_get_graph(new_component);
+ if (new_graph) {
+ status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
+ goto end;
+ }
+
+ if (get_component_port_counts(origin, &origin_input_port_count,
+ &origin_output_port_count)) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+ if (get_component_port_counts(new_component, &new_input_port_count,
+ &new_output_port_count)) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ if (origin_input_port_count != new_input_port_count ||
+ origin_output_port_count != new_output_port_count) {
+ status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ /* Replicate input connections. */
+ for (port_index = 0; port_index< origin_input_port_count; port_index++) {
+ uint64_t connection_count, connection_index;
+
+ origin_port = get_input_port(origin, port_index);
+ if (!origin_port) {
+ status = BT_GRAPH_STATUS_ERROR;
+ goto error_disconnect;
+ }
+ new_port = get_input_port(new_component, port_index);
+ if (!new_port) {
+ status = BT_GRAPH_STATUS_ERROR;
+ goto error_disconnect;
+ }
+
+ if (bt_port_get_connection_count(origin_port, &connection_count) !=
+ BT_PORT_STATUS_OK) {
+ status = BT_GRAPH_STATUS_ERROR;
+ goto error_disconnect;
+ }
+
+ for (connection_index = 0; connection_index < connection_count;
+ connection_index++) {
+ origin_connection = bt_port_get_connection(origin_port,
+ connection_index);
+ if (!origin_connection) {
+ goto error_disconnect;
+ }
+
+ upstream_port = bt_connection_get_output_port(
+ origin_connection);
+ if (!upstream_port) {
+ goto error_disconnect;
+ }
+
+ new_connection = bt_graph_connect(graph, upstream_port,
+ new_port);
+ if (!new_connection) {
+ goto error_disconnect;
+ }
+
+ BT_PUT(upstream_port);
+ BT_PUT(origin_connection);
+ BT_PUT(new_connection);
+ }
+ BT_PUT(origin_port);
+ BT_PUT(new_port);
+ }
+
+ /* Replicate output connections. */
+ for (port_index = 0; port_index< origin_output_port_count; port_index++) {
+ uint64_t connection_count, connection_index;
+
+ origin_port = get_output_port(origin, port_index);
+ if (!origin_port) {
+ status = BT_GRAPH_STATUS_ERROR;
+ goto error_disconnect;
+ }
+ new_port = get_output_port(new_component, port_index);
+ if (!new_port) {
+ status = BT_GRAPH_STATUS_ERROR;
+ goto error_disconnect;
+ }
+
+ if (bt_port_get_connection_count(origin_port, &connection_count) !=
+ BT_PORT_STATUS_OK) {
+ status = BT_GRAPH_STATUS_ERROR;
+ goto error_disconnect;
+ }
+
+ for (connection_index = 0; connection_index < connection_count;
+ connection_index++) {
+ origin_connection = bt_port_get_connection(origin_port,
+ connection_index);
+ if (!origin_connection) {
+ goto error_disconnect;
+ }
+
+ downstream_port = bt_connection_get_input_port(
+ origin_connection);
+ if (!downstream_port) {
+ goto error_disconnect;
+ }
+
+ new_connection = bt_graph_connect(graph, new_port,
+ downstream_port);
+ if (!new_connection) {
+ goto error_disconnect;
+ }
+
+ BT_PUT(downstream_port);
+ BT_PUT(origin_connection);
+ BT_PUT(new_connection);
+ }
+ BT_PUT(origin_port);
+ BT_PUT(new_port);
+ }
+end:
+ bt_put(origin_graph);
+ bt_put(new_graph);
+ bt_put(origin_port);
+ bt_put(new_port);
+ bt_put(upstream_port);
+ bt_put(downstream_port);
+ bt_put(origin_connection);
+ bt_put(new_connection);
+ return status;
+error_disconnect:
+ /* Destroy all connections of the new component. */
+ /* FIXME. */
+ goto end;
+}
+
+enum bt_component_status bt_graph_consume(struct bt_graph *graph)
+{
+ struct bt_component *sink;
+ enum bt_component_status status;
+ GList *current_node;
+
+ if (!graph) {
+ status = BT_COMPONENT_STATUS_INVALID;
+ goto end;
+ }
+
+ if (g_queue_is_empty(graph->sinks_to_consume)) {
+ status = BT_COMPONENT_STATUS_END;
+ goto end;
+ }
+
+ current_node = g_queue_pop_head_link(graph->sinks_to_consume);
+ sink = current_node->data;
+ status = bt_component_sink_consume(sink);
+ if (status != BT_COMPONENT_STATUS_END) {
+ g_queue_push_tail_link(graph->sinks_to_consume, current_node);
+ goto end;
+ }
+
+ /* End reached, the node is not added back to the queue and free'd. */
+ g_queue_delete_link(graph->sinks_to_consume, current_node);
+
+ /* Don't forward an END status if there are sinks left to consume. */
+ if (!g_queue_is_empty(graph->sinks_to_consume)) {
+ status = BT_GRAPH_STATUS_OK;
+ goto end;
+ }
+end:
+ return status;
+}
+
+enum bt_graph_status bt_graph_run(struct bt_graph *graph,
+ enum bt_component_status *_component_status)
+{
+ enum bt_component_status component_status;
+ enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
+
+ if (!graph) {
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto error;
+ }
+
+ do {
+ component_status = bt_graph_consume(graph);
+ if (component_status == BT_COMPONENT_STATUS_AGAIN) {
+ /*
+ * 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.
+ */
+ if (graph->sinks_to_consume->length > 1) {
+ component_status = BT_COMPONENT_STATUS_OK;
+ }
+ }
+ } while (component_status == BT_COMPONENT_STATUS_OK);
+
+ if (_component_status) {
+ *_component_status = component_status;
+ }
+
+ if (g_queue_is_empty(graph->sinks_to_consume)) {
+ graph_status = BT_GRAPH_STATUS_END;
+ } else if (component_status == BT_COMPONENT_STATUS_AGAIN) {
+ graph_status = BT_GRAPH_STATUS_AGAIN;
+ } else {
+ graph_status = BT_GRAPH_STATUS_ERROR;
+ }
+error:
+ return graph_status;
+}
--- /dev/null
+/*
+ * port.c
+ *
+ * Babeltrace Port
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/component/component-internal.h>
+#include <babeltrace/component/port-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler.h>
+
+static
+void bt_port_destroy(struct bt_object *obj)
+{
+ struct bt_port *port = container_of(obj, struct bt_port, base);
+
+ if (port->name) {
+ g_string_free(port->name, TRUE);
+ }
+ if (port->connections) {
+ g_ptr_array_free(port->connections, TRUE);
+ }
+ g_free(port);
+}
+
+BT_HIDDEN
+struct bt_port *bt_port_create(struct bt_component *parent_component,
+ enum bt_port_type type, const char *name)
+{
+ struct bt_port *port;
+
+ assert(name);
+ assert(parent_component);
+ assert(type == BT_PORT_TYPE_INPUT || type == BT_PORT_TYPE_OUTPUT);
+
+ if (*name == '\0') {
+ port = NULL;
+ goto end;
+ }
+
+ port = g_new0(struct bt_port, 1);
+ if (!port) {
+ goto end;
+ }
+
+ bt_object_init(port, bt_port_destroy);
+ port->name = g_string_new(name);
+ if (!port->name) {
+ BT_PUT(port);
+ goto end;
+ }
+
+ port->type = type;
+ port->connections = g_ptr_array_new();
+ if (!port->connections) {
+ BT_PUT(port);
+ goto end;
+ }
+
+ port->max_connection_count = 1;
+
+ bt_object_set_parent(port, &parent_component->base);
+end:
+ return port;
+}
+
+const char *bt_port_get_name(struct bt_port *port)
+{
+ return port ? port->name->str : NULL;
+}
+
+enum bt_port_type bt_port_get_type(struct bt_port *port)
+{
+ return port ? port->type : BT_PORT_TYPE_UNKOWN;
+}
+
+enum bt_port_status bt_port_get_connection_count(struct bt_port *port,
+ uint64_t *count)
+{
+ enum bt_port_status status = BT_PORT_STATUS_OK;
+
+ if (!port || !count) {
+ status = BT_PORT_STATUS_INVALID;
+ goto end;
+ }
+
+ *count = (uint64_t) port->connections->len;
+end:
+ return status;
+}
+
+struct bt_connection *bt_port_get_connection(struct bt_port *port, int index)
+{
+ struct bt_connection *connection;
+
+ if (!port || index < 0 || index >= port->connections->len) {
+ connection = NULL;
+ goto end;
+ }
+
+ connection = bt_get(g_ptr_array_index(port->connections, index));
+end:
+ return connection;
+}
+
+struct bt_component *bt_port_get_component(struct bt_port *port)
+{
+ return (struct bt_component *) bt_object_get_parent(port);
+}
+
+BT_HIDDEN
+int bt_port_add_connection(struct bt_port *port,
+ struct bt_connection *connection)
+{
+ int ret = 0;
+
+ if (port->connections->len == port->max_connection_count) {
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * Don't take a reference on connection as its existence is guaranteed
+ * by the existence of the graph in which the connection exists.
+ */
+ g_ptr_array_add(port->connections, connection);
+end:
+ return ret;
+}
+
+enum bt_port_status bt_port_get_maximum_connection_count(
+ struct bt_port *port, uint64_t *count)
+{
+ enum bt_port_status status = BT_PORT_STATUS_OK;
+
+ if (!port || !count) {
+ status = BT_PORT_STATUS_INVALID;
+ goto end;
+ }
+
+ *count = port->max_connection_count;
+end:
+ return status;
+}
+
+enum bt_port_status bt_port_set_maximum_connection_count(
+ struct bt_port *port, uint64_t count)
+{
+ enum bt_port_status status = BT_PORT_STATUS_OK;
+
+ if (!port || count < port->connections->len || count == 0) {
+ status = BT_PORT_STATUS_INVALID;
+ goto end;
+ }
+
+ port->max_connection_count = count;
+end:
+ return status;
+}
#include <babeltrace/compiler.h>
#include <babeltrace/component/component-source-internal.h>
#include <babeltrace/component/component-internal.h>
-#include <babeltrace/component/component-port-internal.h>
+#include <babeltrace/component/port-internal.h>
#include <babeltrace/component/notification/iterator.h>
#include <babeltrace/component/notification/iterator-internal.h>
#include <babeltrace/plugin/plugin-dev.h>
#include <babeltrace/component/component.h>
#include <babeltrace/component/component-sink.h>
-#include <babeltrace/component/component-port.h>
-#include <babeltrace/component/component-connection.h>
+#include <babeltrace/component/port.h>
+#include <babeltrace/component/connection.h>
#include <babeltrace/component/notification/notification.h>
#include <babeltrace/component/notification/iterator.h>
#include <babeltrace/component/notification/event.h>
#include <glib.h>
#include <babeltrace/component/component.h>
-#include <babeltrace/component/component-port.h>
-#include <babeltrace/component/component-connection.h>
+#include <babeltrace/component/port.h>
+#include <babeltrace/component/connection.h>
struct dummy {
GPtrArray *iterators;
#include <babeltrace/component/notification/stream.h>
#include <babeltrace/component/notification/packet.h>
#include <babeltrace/component/component-filter.h>
-#include <babeltrace/component/component-port.h>
-#include <babeltrace/component/component-connection.h>
+#include <babeltrace/component/port.h>
+#include <babeltrace/component/connection.h>
#include <babeltrace/ctf-ir/event.h>
#include <babeltrace/ctf-ir/stream.h>
#include <babeltrace/ctf-ir/stream-class.h>
#include <babeltrace/plugin/plugin-dev.h>
#include <babeltrace/component/component.h>
#include <babeltrace/component/component-sink.h>
-#include <babeltrace/component/component-port.h>
-#include <babeltrace/component/component-connection.h>
+#include <babeltrace/component/port.h>
+#include <babeltrace/component/connection.h>
#include <babeltrace/component/notification/notification.h>
#include <babeltrace/component/notification/iterator.h>
#include <babeltrace/component/notification/event.h>