From: Jérémie Galarneau Date: Thu, 23 Feb 2017 13:45:01 +0000 (-0500) Subject: Remove component prefix from graph, connection and port filenames X-Git-Tag: v2.0.0-pre1~455 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=7d55361f7b41ed8d44a71c17dfeecd316ca77460 Remove component prefix from graph, connection and port filenames Signed-off-by: Jérémie Galarneau --- diff --git a/converter/babeltrace.c b/converter/babeltrace.c index 9bc282d7..aa985a34 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -34,9 +34,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/include/Makefile.am b/include/Makefile.am index 9ae5d5be..ba2ad2bf 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -57,9 +57,9 @@ babeltracecomponentinclude_HEADERS = \ 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 @@ -129,10 +129,10 @@ noinst_HEADERS = \ 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 \ diff --git a/include/babeltrace/component/component-connection-internal.h b/include/babeltrace/component/component-connection-internal.h deleted file mode 100644 index c552636e..00000000 --- a/include/babeltrace/component/component-connection-internal.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H -#define BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H - -/* - * BabelTrace - Component Connection Internal - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 -#include - -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 */ diff --git a/include/babeltrace/component/component-connection.h b/include/babeltrace/component/component-connection.h deleted file mode 100644 index 7bcebcb8..00000000 --- a/include/babeltrace/component/component-connection.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef BABELTRACE_COMPONENT_CONNECTION_H -#define BABELTRACE_COMPONENT_CONNECTION_H - -/* - * BabelTrace - Babeltrace Component Connection Interface - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 */ diff --git a/include/babeltrace/component/component-graph-internal.h b/include/babeltrace/component/component-graph-internal.h deleted file mode 100644 index 615f4aaf..00000000 --- a/include/babeltrace/component/component-graph-internal.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H -#define BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H - -/* - * BabelTrace - Component Graph Internal - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 -#include -#include -#include - -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 */ diff --git a/include/babeltrace/component/component-graph.h b/include/babeltrace/component/component-graph.h deleted file mode 100644 index 814218fe..00000000 --- a/include/babeltrace/component/component-graph.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef BABELTRACE_COMPONENT_GRAPH_H -#define BABELTRACE_COMPONENT_GRAPH_H - -/* - * BabelTrace - Babeltrace Graph Interface - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 - -#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 */ diff --git a/include/babeltrace/component/component-internal.h b/include/babeltrace/component/component-internal.h index b6dfc880..e70f9e96 100644 --- a/include/babeltrace/component/component-internal.h +++ b/include/babeltrace/component/component-internal.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/babeltrace/component/component-port-internal.h b/include/babeltrace/component/component-port-internal.h deleted file mode 100644 index 39b19e33..00000000 --- a/include/babeltrace/component/component-port-internal.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BABELTRACE_COMPONENT_PORT_INTERNAL_H -#define BABELTRACE_COMPONENT_PORT_INTERNAL_H - -/* - * BabelTrace - Babeltrace Component Port - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 - -#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 */ diff --git a/include/babeltrace/component/component-port.h b/include/babeltrace/component/component-port.h deleted file mode 100644 index fe372c4b..00000000 --- a/include/babeltrace/component/component-port.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef BABELTRACE_COMPONENT_PORT_H -#define BABELTRACE_COMPONENT_PORT_H - -/* - * BabelTrace - Babeltrace Component Connection Interface - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 - -#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 */ diff --git a/include/babeltrace/component/connection-internal.h b/include/babeltrace/component/connection-internal.h new file mode 100644 index 00000000..d2f51ca0 --- /dev/null +++ b/include/babeltrace/component/connection-internal.h @@ -0,0 +1,56 @@ +#ifndef BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H +#define BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H + +/* + * BabelTrace - Component Connection Internal + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 +#include + +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 */ diff --git a/include/babeltrace/component/connection.h b/include/babeltrace/component/connection.h new file mode 100644 index 00000000..7bcebcb8 --- /dev/null +++ b/include/babeltrace/component/connection.h @@ -0,0 +1,51 @@ +#ifndef BABELTRACE_COMPONENT_CONNECTION_H +#define BABELTRACE_COMPONENT_CONNECTION_H + +/* + * BabelTrace - Babeltrace Component Connection Interface + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 */ diff --git a/include/babeltrace/component/graph-internal.h b/include/babeltrace/component/graph-internal.h new file mode 100644 index 00000000..7da6255f --- /dev/null +++ b/include/babeltrace/component/graph-internal.h @@ -0,0 +1,56 @@ +#ifndef BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H +#define BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H + +/* + * BabelTrace - Component Graph Internal + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 +#include +#include +#include + +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 */ diff --git a/include/babeltrace/component/graph.h b/include/babeltrace/component/graph.h new file mode 100644 index 00000000..814218fe --- /dev/null +++ b/include/babeltrace/component/graph.h @@ -0,0 +1,96 @@ +#ifndef BABELTRACE_COMPONENT_GRAPH_H +#define BABELTRACE_COMPONENT_GRAPH_H + +/* + * BabelTrace - Babeltrace Graph Interface + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 + +#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 */ diff --git a/include/babeltrace/component/port-internal.h b/include/babeltrace/component/port-internal.h new file mode 100644 index 00000000..437ba827 --- /dev/null +++ b/include/babeltrace/component/port-internal.h @@ -0,0 +1,56 @@ +#ifndef BABELTRACE_COMPONENT_PORT_INTERNAL_H +#define BABELTRACE_COMPONENT_PORT_INTERNAL_H + +/* + * BabelTrace - Babeltrace Component Port + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 + +#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 */ diff --git a/include/babeltrace/component/port.h b/include/babeltrace/component/port.h new file mode 100644 index 00000000..fe372c4b --- /dev/null +++ b/include/babeltrace/component/port.h @@ -0,0 +1,73 @@ +#ifndef BABELTRACE_COMPONENT_PORT_H +#define BABELTRACE_COMPONENT_PORT_H + +/* + * BabelTrace - Babeltrace Component Connection Interface + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 + +#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 */ diff --git a/lib/component/Makefile.am b/lib/component/Makefile.am index 901c25fb..7471a4b5 100644 --- a/lib/component/Makefile.am +++ b/lib/component/Makefile.am @@ -8,9 +8,9 @@ noinst_LTLIBRARIES = libcomponent.la 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 \ diff --git a/lib/component/component-connection.c b/lib/component/component-connection.c deleted file mode 100644 index 3b509c39..00000000 --- a/lib/component/component-connection.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * component-connection.c - * - * Babeltrace Connection - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -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; -} diff --git a/lib/component/component-graph.c b/lib/component/component-graph.c deleted file mode 100644 index 57a8cc41..00000000 --- a/lib/component/component-graph.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * component-graph.c - * - * Babeltrace Plugin Component Graph - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -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; -} diff --git a/lib/component/component-port.c b/lib/component/component-port.c deleted file mode 100644 index b08da58d..00000000 --- a/lib/component/component-port.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * component-port.c - * - * Babeltrace Port - * - * Copyright 2017 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * 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 -#include -#include -#include - -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; -} diff --git a/lib/component/component.c b/lib/component/component.c index 8056db14..50eb4ea2 100644 --- a/lib/component/component.c +++ b/lib/component/component.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/component/connection.c b/lib/component/connection.c new file mode 100644 index 00000000..8867e4f0 --- /dev/null +++ b/lib/component/connection.c @@ -0,0 +1,121 @@ +/* + * connection.c + * + * Babeltrace Connection + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/lib/component/graph.c b/lib/component/graph.c new file mode 100644 index 00000000..4d6c2802 --- /dev/null +++ b/lib/component/graph.c @@ -0,0 +1,525 @@ +/* + * graph.c + * + * Babeltrace Plugin Component Graph + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/lib/component/port.c b/lib/component/port.c new file mode 100644 index 00000000..8aa9a462 --- /dev/null +++ b/lib/component/port.c @@ -0,0 +1,181 @@ +/* + * port.c + * + * Babeltrace Port + * + * Copyright 2017 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * 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 +#include +#include +#include + +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; +} diff --git a/lib/component/source.c b/lib/component/source.c index adbf8ed7..e0c717b3 100644 --- a/lib/component/source.c +++ b/lib/component/source.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/text/text.c b/plugins/text/text.c index 8a916fc3..cbb86e0c 100644 --- a/plugins/text/text.c +++ b/plugins/text/text.c @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/plugins/utils/dummy/dummy.h b/plugins/utils/dummy/dummy.h index a0c674e3..35e5af67 100644 --- a/plugins/utils/dummy/dummy.h +++ b/plugins/utils/dummy/dummy.h @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include struct dummy { GPtrArray *iterators; diff --git a/plugins/utils/trimmer/iterator.c b/plugins/utils/trimmer/iterator.c index 9b54a166..bf3229ee 100644 --- a/plugins/utils/trimmer/iterator.c +++ b/plugins/utils/trimmer/iterator.c @@ -34,8 +34,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/plugins/writer/writer.c b/plugins/writer/writer.c index 1c8faab1..d7765e7c 100644 --- a/plugins/writer/writer.c +++ b/plugins/writer/writer.c @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include