"comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
comp, comp ? bt_component_get_name(comp) : "",
port, bt_port_get_name(port));
+
+ if (!ctx->connect_ports) {
+ goto end;
+ }
+
if (!comp) {
BT_LOGW_STR("Port has no component.");
goto end;
goto error;
}
- comp = bt_component_create(comp_cls,
- cfg_comp->instance_name->str, cfg_comp->params);
- if (!comp) {
+ ret = bt_graph_add_component(ctx->graph, comp_cls,
+ cfg_comp->instance_name->str, cfg_comp->params, &comp);
+ if (ret) {
BT_LOGE("Cannot create component: plugin-name=\"%s\", "
"comp-cls-name=\"%s\", comp-cls-type=%d, "
"comp-name=\"%s\"",
return "BT_GRAPH_STATUS_END";
case BT_GRAPH_STATUS_OK:
return "BT_GRAPH_STATUS_OK";
- case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH:
- return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH";
case BT_GRAPH_STATUS_INVALID:
return "BT_GRAPH_STATUS_INVALID";
case BT_GRAPH_STATUS_NO_SINK:
*/
BT_HIDDEN
struct bt_component *bt_component_filter_create(
- struct bt_component_class *class, struct bt_value *params);
+ struct bt_component_class *class);
BT_HIDDEN
void bt_component_filter_destroy(struct bt_component *component);
/* Array of struct bt_component_destroy_listener */
GArray *destroy_listeners;
+
+ bool initialized;
};
static inline
return (void *) comp->base.parent;
}
+BT_HIDDEN
+enum bt_component_status bt_component_create(
+ struct bt_component_class *component_class,
+ const char *name, struct bt_component **component);
+
BT_HIDDEN
enum bt_component_status bt_component_accept_port_connection(
struct bt_component *component, struct bt_port *self_port,
*/
BT_HIDDEN
struct bt_component *bt_component_sink_create(
- struct bt_component_class *class, struct bt_value *params);
+ struct bt_component_class *class);
BT_HIDDEN
void bt_component_sink_destroy(struct bt_component *component);
*/
BT_HIDDEN
struct bt_component *bt_component_source_create(
- struct bt_component_class *class, struct bt_value *params);
+ struct bt_component_class *class);
BT_HIDDEN
void bt_component_source_destroy(struct bt_component *component);
struct bt_value;
struct bt_port;
-/**
- * Create an instance of a component from a component class.
- *
- * @param component_class Component class of which to create an instance
- * @param name Name of the new component instance, optional
- * @param params A dictionary of component parameters
- * @returns Returns a pointer to a new component instance
- */
-extern struct bt_component *bt_component_create(
- struct bt_component_class *component_class, const char *name,
- struct bt_value *params);
-
-extern struct bt_component *bt_component_create_with_init_method_data(
- struct bt_component_class *component_class, const char *name,
- struct bt_value *params, void *init_method_data);
-
/**
* Get component's name.
*
return "BT_GRAPH_STATUS_END";
case BT_GRAPH_STATUS_OK:
return "BT_GRAPH_STATUS_OK";
- case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH:
- return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH";
case BT_GRAPH_STATUS_INVALID:
return "BT_GRAPH_STATUS_INVALID";
case BT_GRAPH_STATUS_NO_SINK:
/** Downstream component does not support multiple inputs. */
BT_GRAPH_STATUS_END = 1,
BT_GRAPH_STATUS_OK = 0,
- /** Component is already part of another graph. */
- BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH = -2,
/** Invalid arguments. */
BT_GRAPH_STATUS_INVALID = -22,
/** No sink in graph. */
extern struct bt_graph *bt_graph_create(void);
+extern enum bt_graph_status bt_graph_add_component(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ struct bt_component **component);
+
+extern enum bt_graph_status bt_graph_add_component_with_init_method_data(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ void *init_method_data,
+ struct bt_component **component);
+
/**
* Creates a connection between two components using the two ports specified
* and adds the connection and components (if not already added) to the graph.
obj->ref_count.count);
#endif
- if (obj && obj->release && !bt_object_get_ref_count(obj)) {
+ if (obj && obj->release && bt_object_get_ref_count(obj) == 0) {
obj->release(obj);
}
}
static
struct bt_component * (* const component_create_funcs[])(
- struct bt_component_class *, struct bt_value *) = {
+ struct bt_component_class *) = {
[BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_create,
[BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_create,
[BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
component_class = component->class;
/*
- * User data is destroyed first, followed by the concrete component
- * instance.
+ * User data is destroyed first, followed by the concrete
+ * component instance. Do not finalize if the component's user
+ * initialization method failed in the first place.
*/
- if (component->class->methods.finalize) {
+ if (component->initialized && component->class->methods.finalize) {
BT_LOGD_STR("Calling user's finalization method.");
component->class->methods.finalize(
bt_private_component_from_component(component));
return (int64_t) comp->output_ports->len;
}
-struct bt_component *bt_component_create_with_init_method_data(
- struct bt_component_class *component_class, const char *name,
- struct bt_value *params, void *init_method_data)
+enum bt_component_status bt_component_create(
+ struct bt_component_class *component_class,
+ const char *name, struct bt_component **user_component)
{
- int ret;
+ enum bt_component_status status = BT_COMPONENT_STATUS_OK;
struct bt_component *component = NULL;
enum bt_component_class_type type;
- bt_get(params);
-
- if (!component_class) {
- BT_LOGW_STR("Invalid parameter: component class is NULL.");
- goto end;
- }
+ assert(user_component);
+ assert(component_class);
+ assert(name);
type = bt_component_class_get_type(component_class);
- if (type <= BT_COMPONENT_CLASS_TYPE_UNKNOWN ||
- type > BT_COMPONENT_CLASS_TYPE_FILTER) {
- BT_LOGW("Invalid parameter: unknown component class type: "
- "type=%s", bt_component_class_type_string(type));
- goto end;
- }
-
- BT_LOGD("Creating component from component class: "
- "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\", "
- "params-addr=%p, init-method-data-addr=%p",
- component_class, bt_component_class_type_string(type),
- name, params, init_method_data);
-
- /*
- * Parameters must be a map value, but we create a convenient
- * empty one if it's NULL.
- */
- if (params) {
- if (!bt_value_is_map(params)) {
- BT_LOGW("Invalid parameter: initialization parameters must be a map value: "
- "type=%s",
- bt_value_type_string(bt_value_get_type(params)));
- goto end;
- }
- } else {
- params = bt_value_map_create();
- if (!params) {
- BT_LOGE_STR("Cannot create map value object.");
- goto end;
- }
- }
-
- component = component_create_funcs[type](component_class, params);
+ BT_LOGD("Creating empty component from component class: "
+ "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\"",
+ component_class, bt_component_class_type_string(type), name);
+ component = component_create_funcs[type](component_class);
if (!component) {
BT_LOGE_STR("Cannot create specific component object.");
+ status = BT_COMPONENT_STATUS_NOMEM;
goto end;
}
component->name = g_string_new(name);
if (!component->name) {
BT_LOGE_STR("Failed to allocate one GString.");
- BT_PUT(component);
+ status = BT_COMPONENT_STATUS_NOMEM;
goto end;
}
bt_object_release);
if (!component->input_ports) {
BT_LOGE_STR("Failed to allocate one GPtrArray.");
- BT_PUT(component);
+ status = BT_COMPONENT_STATUS_NOMEM;
goto end;
}
bt_object_release);
if (!component->output_ports) {
BT_LOGE_STR("Failed to allocate one GPtrArray.");
- BT_PUT(component);
+ status = BT_COMPONENT_STATUS_NOMEM;
goto end;
}
sizeof(struct bt_component_destroy_listener));
if (!component->destroy_listeners) {
BT_LOGE_STR("Failed to allocate one GArray.");
- BT_PUT(component);
+ status = BT_COMPONENT_STATUS_NOMEM;
goto end;
}
- if (component_class->methods.init) {
- BT_LOGD_STR("Calling user's initialization method.");
- ret = component_class->methods.init(
- bt_private_component_from_component(component), params,
- init_method_data);
- BT_LOGD("User method returned: status=%s",
- bt_component_status_string(ret));
- if (ret != BT_COMPONENT_STATUS_OK) {
- BT_LOGW_STR("Initialization method failed.");
- BT_PUT(component);
- goto end;
- }
- }
-
- BT_LOGD_STR("Freezing component class.");
- bt_component_class_freeze(component->class);
- BT_LOGD("Created component from component class: "
- "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\", "
- "params-addr=%p, init-method-data-addr=%p, comp-addr=%p",
- component_class, bt_component_class_type_string(type),
- name, params, init_method_data, component);
+ BT_LOGD("Created empty component from component class: "
+ "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\", comp-addr=%p",
+ component_class, bt_component_class_type_string(type), name,
+ component);
+ BT_MOVE(*user_component, component);
end:
- bt_put(params);
- return component;
-}
-
-struct bt_component *bt_component_create(
- struct bt_component_class *component_class, const char *name,
- struct bt_value *params)
-{
- /* bt_component_create_with_init_method_data() logs details */
- return bt_component_create_with_init_method_data(component_class, name,
- params, NULL);
+ bt_put(component);
+ return status;
}
const char *bt_component_get_name(struct bt_component *component)
void bt_component_set_graph(struct bt_component *component,
struct bt_graph *graph)
{
- struct bt_object *parent = bt_object_get_parent(&component->base);
-
- assert(!parent || parent == &graph->base);
- if (!parent) {
- bt_object_set_parent(component, &graph->base);
- }
- bt_put(parent);
+ bt_object_set_parent(component, graph ? &graph->base : NULL);
}
struct bt_graph *bt_component_get_graph(
BT_HIDDEN
struct bt_component *bt_component_filter_create(
- struct bt_component_class *class, struct bt_value *params)
+ struct bt_component_class *class)
{
struct bt_component_filter *filter = NULL;
#include <babeltrace/graph/port.h>
#include <babeltrace/compiler-internal.h>
#include <babeltrace/types.h>
+#include <babeltrace/values.h>
+#include <babeltrace/values-internal.h>
#include <unistd.h>
#include <glib.h>
struct bt_component *upstream_component = NULL;
struct bt_component *downstream_component = NULL;
enum bt_component_status component_status;
- bt_bool upstream_was_already_in_graph;
- bt_bool downstream_was_already_in_graph;
if (!graph) {
BT_LOGW_STR("Invalid parameter: graph is NULL.");
upstream_component, bt_component_get_name(upstream_component),
downstream_component, bt_component_get_name(downstream_component));
- /* Ensure the components are not already part of another graph. */
- upstream_graph = bt_component_get_graph(upstream_component);
- if (upstream_graph && (graph != upstream_graph)) {
- BT_LOGW("Invalid parameter: upstream port's component is already part of another graph: "
- "other-graph-addr=%p", upstream_graph);
- status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
- goto end;
- }
- upstream_was_already_in_graph = (graph == upstream_graph);
- downstream_graph = bt_component_get_graph(downstream_component);
- if (downstream_graph && (graph != downstream_graph)) {
- BT_LOGW("Invalid parameter: downstream port's component is already part of another graph: "
- "other-graph-addr=%p", downstream_graph);
- status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
- goto end;
- }
- downstream_was_already_in_graph = (graph == downstream_graph);
-
/*
* At this point the ports are not connected yet. Both
* components need to accept an eventual connection to their
*/
g_ptr_array_add(graph->connections, connection);
- if (!upstream_was_already_in_graph) {
- g_ptr_array_add(graph->components, upstream_component);
- bt_component_set_graph(upstream_component, graph);
- }
- if (!downstream_was_already_in_graph) {
- g_ptr_array_add(graph->components, downstream_component);
- bt_component_set_graph(downstream_component, graph);
- 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.
- */
-
/*
* Notify both components that their port is connected.
*/
graph, connection);
g_ptr_array_remove(graph->connections, connection);
}
+
+enum bt_graph_status bt_graph_add_component_with_init_method_data(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ void *init_method_data,
+ struct bt_component **user_component)
+{
+ enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
+ enum bt_component_status comp_status;
+ struct bt_component *component = NULL;
+ enum bt_component_class_type type;
+ size_t i;
+
+ bt_get(params);
+
+ if (!graph) {
+ BT_LOGW_STR("Invalid parameter: graph is NULL.");
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ if (!component_class) {
+ BT_LOGW_STR("Invalid parameter: component class is NULL.");
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ type = bt_component_class_get_type(component_class);
+ BT_LOGD("Adding component to graph: "
+ "graph-addr=%p, comp-cls-addr=%p, "
+ "comp-cls-type=%s, name=\"%s\", params-addr=%p, "
+ "init-method-data-addr=%p",
+ graph, component_class, bt_component_class_type_string(type),
+ name, params, init_method_data);
+
+ if (!name) {
+ BT_LOGW_STR("Invalid parameter: name is NULL.");
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ if (graph->canceled) {
+ BT_LOGW_STR("Invalid parameter: graph is canceled.");
+ graph_status = BT_GRAPH_STATUS_CANCELED;
+ goto end;
+ }
+
+ if (type != BT_COMPONENT_CLASS_TYPE_SOURCE &&
+ type != BT_COMPONENT_CLASS_TYPE_FILTER &&
+ type != BT_COMPONENT_CLASS_TYPE_SINK) {
+ BT_LOGW("Invalid parameter: unknown component class type: "
+ "type=%d", type);
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+
+ for (i = 0; i < graph->components->len; i++) {
+ void *other_comp = graph->components->pdata[i];
+
+ if (strcmp(name, bt_component_get_name(other_comp)) == 0) {
+ BT_LOGW("Invalid parameter: another component with the same name already exists in the graph: "
+ "other-comp-addr=%p, name=\"%s\"",
+ other_comp, name);
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+ }
+
+ /*
+ * Parameters must be a map value, but we create a convenient
+ * empty one if it's NULL.
+ */
+ if (params) {
+ if (!bt_value_is_map(params)) {
+ BT_LOGW("Invalid parameter: initialization parameters must be a map value: "
+ "type=%s",
+ bt_value_type_string(bt_value_get_type(params)));
+ graph_status = BT_GRAPH_STATUS_INVALID;
+ goto end;
+ }
+ } else {
+ params = bt_value_map_create();
+ if (!params) {
+ BT_LOGE_STR("Cannot create map value object.");
+ graph_status = BT_GRAPH_STATUS_NOMEM;
+ goto end;
+ }
+ }
+
+ comp_status = bt_component_create(component_class, name, &component);
+ if (comp_status != BT_COMPONENT_STATUS_OK) {
+ BT_LOGE("Cannot create empty component object: status=%s",
+ bt_component_status_string(comp_status));
+ graph_status = bt_graph_status_from_component_status(
+ comp_status);
+ goto end;
+ }
+
+ /*
+ * The user's initialization method needs to see that this
+ * component is part of the graph. If the user method fails, we
+ * immediately remove the component from the graph's components.
+ */
+ g_ptr_array_add(graph->components, component);
+ bt_component_set_graph(component, graph);
+
+ if (component_class->methods.init) {
+ BT_LOGD_STR("Calling user's initialization method.");
+ comp_status = component_class->methods.init(
+ bt_private_component_from_component(component), params,
+ init_method_data);
+ BT_LOGD("User method returned: status=%s",
+ bt_component_status_string(comp_status));
+ if (comp_status != BT_COMPONENT_STATUS_OK) {
+ BT_LOGW_STR("Initialization method failed.");
+ graph_status = bt_graph_status_from_component_status(
+ comp_status);
+ bt_component_set_graph(component, NULL);
+ g_ptr_array_remove_fast(graph->components, component);
+ goto end;
+ }
+ }
+
+ /*
+ * Mark the component as initialized so that its finalization
+ * method is called when it is destroyed.
+ */
+ component->initialized = true;
+
+ /*
+ * If it's a sink component, it needs to be part of the graph's
+ * sink queue to be consumed by bt_graph_consume().
+ */
+ if (bt_component_is_sink(component)) {
+ g_queue_push_tail(graph->sinks_to_consume, component);
+ }
+
+ /*
+ * Freeze the component class now that it's instantiated at
+ * least once.
+ */
+ BT_LOGD_STR("Freezing component class.");
+ bt_component_class_freeze(component->class);
+ BT_LOGD("Added component to graph: "
+ "graph-addr=%p, comp-cls-addr=%p, "
+ "comp-cls-type=%s, name=\"%s\", params-addr=%p, "
+ "init-method-data-addr=%p, comp-addr=%p",
+ graph, component_class, bt_component_class_type_string(type),
+ name, params, init_method_data, component);
+
+ if (user_component) {
+ /* Move reference to user */
+ *user_component = component;
+ component = NULL;
+ }
+
+end:
+ bt_put(component);
+ bt_put(params);
+ return graph_status;
+}
+
+enum bt_graph_status bt_graph_add_component(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ struct bt_component **component)
+{
+ return bt_graph_add_component_with_init_method_data(graph,
+ component_class, name, params, NULL, component);
+}
BT_HIDDEN
struct bt_component *bt_component_sink_create(
- struct bt_component_class *class, struct bt_value *params)
+ struct bt_component_class *class)
{
struct bt_component_sink *sink = NULL;
BT_HIDDEN
struct bt_component *bt_component_source_create(
- struct bt_component_class *class, struct bt_value *params)
+ struct bt_component_class *class)
{
struct bt_component_source *source = NULL;
}
static
-void create_source_sink(struct bt_component **source,
+void create_source_sink(struct bt_graph *graph, struct bt_component **source,
struct bt_component **sink)
{
struct bt_component_class *src_comp_class;
ret = bt_component_class_source_set_notification_iterator_finalize_method(
src_comp_class, src_iter_finalize);
assert(ret == 0);
- *source = bt_component_create(src_comp_class, "source", NULL);
- assert(*source);
+ ret = bt_graph_add_component(graph, src_comp_class, "source", NULL,
+ source);
+ assert(ret == 0);
/* Create sink component */
sink_comp_class = bt_component_class_sink_create("sink", sink_consume);
ret = bt_component_class_set_port_connected_method(sink_comp_class,
sink_port_connected);
assert(ret == 0);
- *sink = bt_component_create(sink_comp_class, "sink", NULL);
+ ret = bt_graph_add_component(graph, sink_comp_class, "sink", NULL,
+ sink);
+ assert(ret == 0);
bt_put(src_comp_class);
bt_put(sink_comp_class);
clear_test_events();
current_test = test;
diag("test: %s", name);
- create_source_sink(&src_comp, &sink_comp);
graph = bt_graph_create();
assert(graph);
+ create_source_sink(graph, &src_comp, &sink_comp);
/* Connect source to sink */
upstream_port = bt_component_source_get_output_port_by_name(src_comp, "out");
#include "tap/tap.h"
-#define NR_TESTS 69
+#define NR_TESTS 77
enum event_type {
COMP_ACCEPT_PORT_CONNECTION,
}
static
-struct bt_component *create_src(void)
+struct bt_component *create_src(struct bt_graph *graph)
{
- struct bt_component *comp =
- bt_component_create(src_comp_class, "src-comp", NULL);
+ struct bt_component *comp;
+ int ret;
- assert(comp);
+ ret = bt_graph_add_component(graph, src_comp_class, "src-comp", NULL,
+ &comp);
+ assert(ret == 0);
return comp;
}
static
-struct bt_component *create_sink(void)
+struct bt_component *create_sink(struct bt_graph *graph)
{
- struct bt_component *comp =
- bt_component_create(sink_comp_class, "sink-comp", NULL);
+ struct bt_component *comp;
+ int ret;
- assert(comp);
+ ret = bt_graph_add_component(graph, sink_comp_class, "sink-comp",
+ NULL, &comp);
+ assert(ret == 0);
return comp;
}
prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
"sink removes port in consume, then source removes disconnected port");
- src = create_src();
- sink = create_sink();
graph = create_graph();
+ assert(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
src_def_port = bt_component_source_get_output_port_by_name(src, "out");
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
assert(status == 0);
assert(conn);
- /* We're supposed to have 5 events so far */
- ok(events->len == 5, "we have the expected number of events (before consume)");
+ /* We're supposed to have 7 events so far */
+ ok(events->len == 7, "we have the expected number of events (before consume)");
+
+ /* Source's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = src;
+ event.data.graph_port_added.port = src_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = sink;
+ event.data.graph_port_added.port = sink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
/* Source's accept port connection */
event.type = COMP_ACCEPT_PORT_CONNECTION;
prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
"sink removes port in consume");
- src = create_src();
- sink = create_sink();
graph = create_graph();
+ assert(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
src_def_port = bt_component_source_get_output_port_by_name(src, "out");
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
&conn);
assert(status == 0);
- /* We're supposed to have 5 events so far */
- ok(events->len == 5, "we have the expected number of events (before consume)");
+ /* We're supposed to have 7 events so far */
+ ok(events->len == 7, "we have the expected number of events (before consume)");
+
+ /* Source's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = src;
+ event.data.graph_port_added.port = src_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = sink;
+ event.data.graph_port_added.port = sink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
/* Source's accept port connection */
event.type = COMP_ACCEPT_PORT_CONNECTION;
prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
"source adds port in port connected");
- src = create_src();
- sink = create_sink();
graph = create_graph();
+ assert(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
src_def_port = bt_component_source_get_output_port_by_name(src, "out");
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
"hello");
assert(src_hello_port);
- /* We're supposed to have 6 events */
- ok(events->len == 6, "we have the expected number of events");
+ /* We're supposed to have 8 events */
+ ok(events->len == 8, "we have the expected number of events");
+
+ /* Source's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = src;
+ event.data.graph_port_added.port = src_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = sink;
+ event.data.graph_port_added.port = sink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
/* Source's accept port connection */
event.type = COMP_ACCEPT_PORT_CONNECTION;
size_t graph_ports_connected_pos;
prepare_test(TEST_SIMPLE, "simple");
- src = create_src();
- sink = create_sink();
graph = create_graph();
+ assert(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
src_def_port = bt_component_source_get_output_port_by_name(src, "out");
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
&conn);
assert(status == 0);
- /* We're supposed to have 5 events */
- ok(events->len == 5, "we have the expected number of events");
+ /* We're supposed to have 7 events */
+ ok(events->len == 7, "we have the expected number of events");
+
+ /* Source's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = src;
+ event.data.graph_port_added.port = src_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_PORT_ADDED;
+ event.data.graph_port_added.comp = sink;
+ event.data.graph_port_added.port = sink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
/* Source's accept port connection */
event.type = COMP_ACCEPT_PORT_CONNECTION;
#include <babeltrace/ref.h>
#include <babeltrace/values.h>
#include <babeltrace/graph/component.h>
+#include <babeltrace/graph/graph.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct bt_value *results;
struct bt_value *object;
struct bt_value *res_params;
+ struct bt_graph *graph;
const char *object_str;
int ret;
diag("> putting the plugin object here");
BT_PUT(plugin);
- sink_component = bt_component_create(sink_comp_class, NULL, NULL);
- ok(sink_component, "bt_component_create() still works after the plugin object is destroyed");
+ graph = bt_graph_create();
+ assert(graph);
+ ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL,
+ &sink_component);
+ ok(ret == 0 && sink_component,
+ "bt_graph_add_component() still works after the plugin object is destroyed");
BT_PUT(sink_component);
BT_PUT(source_comp_class);
- sink_component = bt_component_create(sink_comp_class, NULL, NULL);
- ok(sink_component, "bt_component_create() still works after the source component class object is destroyed");
+ bt_put(graph);
+ graph = bt_graph_create();
+ assert(graph);
+ ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL,
+ &sink_component);
+ ok(ret == 0 && sink_component,
+ "bt_graph_add_component() still works after the source component class object is destroyed");
BT_PUT(sink_component);
BT_PUT(filter_comp_class);
- sink_component = bt_component_create(sink_comp_class, NULL, NULL);
- ok(sink_component, "bt_component_create() still works after the filter component class object is destroyed");
+ bt_put(graph);
+ graph = bt_graph_create();
+ assert(graph);
+ ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL,
+ &sink_component);
+ ok(ret == 0 && sink_component,
+ "bt_graph_add_component() still works after the filter component class object is destroyed");
BT_PUT(sink_comp_class);
BT_PUT(sink_component);
free(sfs_path);
+ bt_put(graph);
bt_put(plugin_set);
bt_put(object);
bt_put(res_params);
}
static
-void create_source_muxer_sink(struct bt_component **source,
+void create_source_muxer_sink(struct bt_graph *graph,
+ struct bt_component **source,
struct bt_component **muxer,
struct bt_component **sink)
{
ret = bt_component_class_source_set_notification_iterator_finalize_method(
src_comp_class, src_iter_finalize);
assert(ret == 0);
- *source = bt_component_create(src_comp_class, "source", NULL);
- assert(*source);
+ ret = bt_graph_add_component(graph, src_comp_class, "source", NULL, source);
+ assert(ret == 0);
/* Create muxer component */
muxer_comp_class = bt_plugin_find_component_class("utils", "muxer",
BT_COMPONENT_CLASS_TYPE_FILTER);
assert(muxer_comp_class);
- *muxer = bt_component_create(muxer_comp_class, "muxer", NULL);
- assert(*muxer);
+ ret = bt_graph_add_component(graph, muxer_comp_class, "muxer", NULL, muxer);
+ assert(ret == 0);
/* Create sink component */
sink_comp_class = bt_component_class_sink_create("sink", sink_consume);
ret = bt_component_class_set_port_connected_method(sink_comp_class,
sink_port_connected);
assert(ret == 0);
- *sink = bt_component_create(sink_comp_class, "sink", NULL);
+ ret = bt_graph_add_component(graph, sink_comp_class, "sink", NULL, sink);
+ assert(ret == 0);
bt_put(src_comp_class);
bt_put(muxer_comp_class);
clear_test_events();
current_test = test;
diag("test: %s", name);
- create_source_muxer_sink(&src_comp, &muxer_comp, &sink_comp);
graph = bt_graph_create();
assert(graph);
+ create_source_muxer_sink(graph, &src_comp, &muxer_comp, &sink_comp);
/* Connect source output ports to muxer input ports */
if (with_upstream) {
clear_test_events();
current_test = TEST_SINGLE_END_THEN_MULTIPLE_FULL;
diag("test: single end then multiple full");
- create_source_muxer_sink(&src_comp, &muxer_comp, &sink_comp);
graph = bt_graph_create();
assert(graph);
+ create_source_muxer_sink(graph, &src_comp, &muxer_comp, &sink_comp);
graph_listener_data.graph = graph;
graph_listener_data.source = src_comp;
graph_listener_data.muxer = muxer_comp;
clear_test_events();
current_test = TEST_SINGLE_AGAIN_END_THEN_MULTIPLE_FULL;
diag("test: single again then end then multiple full");
- create_source_muxer_sink(&src_comp, &muxer_comp, &sink_comp);
graph = bt_graph_create();
assert(graph);
+ create_source_muxer_sink(graph, &src_comp, &muxer_comp, &sink_comp);
graph_listener_data.graph = graph;
graph_listener_data.source = src_comp;
graph_listener_data.muxer = muxer_comp;