This patch allows a component to remove one of its own ports at anytime.
Removing a connected port has the side effect of also disconnecting it.
This patch also allows any user (graph's creator or component, for
example) to disconnect a component's port.
A component can remove one of its port with
bt_port_remove_from_component(). This function only needs the port
object because the removing component is its parent. Note that this
function does not check in any way that the removing component is the
parent of the port to remove from its parent, so any component or even
the graph's user could remove any component's port. This is prohibited
by the API's contract, but it's not enforced. It should be documented
accordingly.
You can disconnect a port with bt_port_disconnect(). When you call this
function, both upstream and downstream ports of the port's current
connection are disconnected, that is, they become available again for
bt_graph_connect().
When a port is disconnected with bt_port_remove_from_component(), the
parent component's of the connection's other port is called back ("port
disconnected" method) to notify it that one of its ports lost a
connection. Then the component is free to keep this port as an available
port, or to remove it too.
When a port is disconnected with bt_port_disconnect(), both
components are called back ("port disconnected method").
The existing iterators on a connection which is dropped (ports are
disconnected) are left as is: they still work.
The "new connection" optional method is renamed to "accept port
connection": this method can return
BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION to explicitly refuse the
new connection.
With this patch, only one connection per port is allowed. This
simplifies the model. One-to-many connections can be replaced with
a "tee" filter. Thus this patch removes the concept of a maximum number
of connections per port (it's always one).
With this patch, a component can add a new port at anytime, not just
during its initialization.
Also in this patch: the input and output ports are part of the
bt_component object. The public API is not changed. This avoids some
code duplication.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
while (true) {
enum bt_graph_status graph_status;
- graph_status = bt_graph_run(graph, NULL);
+ graph_status = bt_graph_run(graph);
switch (graph_status) {
case BT_GRAPH_STATUS_AGAIN:
/* Wait for an arbitraty 500 ms. */
bt_component_class_init_method init;
bt_component_class_destroy_method destroy;
bt_component_class_query_method query;
- bt_component_class_new_connection_method new_connection_method;
+ bt_component_class_accept_port_connection_method accept_port_connection;
+ bt_component_class_port_disconnected_method port_disconnected;
} methods;
/* Array of struct bt_component_class_destroy_listener */
GArray *destroy_listeners;
struct bt_component_class *component_class,
const char *object, struct bt_value *params);
-typedef enum bt_component_status (*bt_component_class_new_connection_method)(
- struct bt_port *own_port, struct bt_connection *connection);
+typedef enum bt_component_status (*bt_component_class_accept_port_connection_method)(
+ struct bt_component *component, struct bt_port *port);
+
+typedef void (*bt_component_class_port_disconnected_method)(
+ struct bt_component *component, struct bt_port *port);
extern int bt_component_class_set_init_method(
struct bt_component_class *component_class,
struct bt_component_class *component_class,
bt_component_class_destroy_method destroy_method);
-extern int bt_component_class_set_new_connection_method(
+extern int bt_component_class_set_accept_port_connection_method(
+ struct bt_component_class *component_class,
+ bt_component_class_accept_port_connection_method accept_port_connection_method);
+
+extern int bt_component_class_set_port_disconnected_method(
struct bt_component_class *component_class,
- bt_component_class_new_connection_method new_connection_method);
+ bt_component_class_port_disconnected_method port_disconnected_method);
+
+extern int bt_component_class_set_query_method(
+ struct bt_component_class *component_class,
+ bt_component_class_query_method query_method);
extern int bt_component_class_set_description(
struct bt_component_class *component_class,
extern const char *bt_component_class_get_help(
struct bt_component_class *component_class);
-extern int bt_component_class_set_query_method(
- struct bt_component_class *component_class,
- bt_component_class_query_method query_method);
-
-extern int bt_component_class_set_new_connection_method(
- struct bt_component_class *component_class,
- bt_component_class_new_connection_method new_connection_method);
-
extern struct bt_value *bt_component_class_query(
struct bt_component_class *component_class,
const char *object, struct bt_value *params);
struct bt_component_filter {
struct bt_component parent;
- GPtrArray *input_ports, *output_ports;
};
/**
struct bt_component *bt_component_filter_create(
struct bt_component_class *class, struct bt_value *params);
+BT_HIDDEN
+void bt_component_filter_destroy(struct bt_component *component);
+
/**
* Validate a filter component.
*
struct bt_component_class *class;
GString *name;
- /**
+ /*
* Internal destroy function specific to a source, filter, or
* sink component object.
*/
bt_component_class_destroy_method destroy;
- /** User-defined data */
+ /* User-defined data */
void *user_data;
- /**
+ /*
* Used to protect operations which may only be used during
* a component's initialization.
*/
bool initializing;
-};
-BT_HIDDEN
-enum bt_component_status bt_component_init(struct bt_component *component,
- bt_component_class_destroy_method destroy);
+ /* Input and output ports (weak references) */
+ GPtrArray *input_ports;
+ GPtrArray *output_ports;
+};
BT_HIDDEN
struct bt_notification_iterator *bt_component_create_iterator(
struct bt_component *component, void *init_method_data);
BT_HIDDEN
-enum bt_component_status bt_component_new_connection(
- struct bt_component *component, struct bt_port *own_port,
- struct bt_connection *connection);
+enum bt_component_status bt_component_accept_port_connection(
+ struct bt_component *component, struct bt_port *self_port);
+
+BT_HIDDEN
+void bt_component_port_disconnected(struct bt_component *comp,
+ struct bt_port *port);
BT_HIDDEN
void bt_component_set_graph(struct bt_component *component,
struct bt_graph *graph);
BT_HIDDEN
-int bt_component_init_input_ports(struct bt_component *component,
- GPtrArray **input_ports);
+uint64_t bt_component_get_input_port_count(struct bt_component *comp);
BT_HIDDEN
-int bt_component_init_output_ports(struct bt_component *component,
- GPtrArray **output_ports);
+uint64_t bt_component_get_output_port_count(struct bt_component *comp);
BT_HIDDEN
-struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name);
+struct bt_port *bt_component_get_input_port_at_index(struct bt_component *comp,
+ int index);
BT_HIDDEN
-struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index);
+struct bt_port *bt_component_get_output_port_at_index(struct bt_component *comp,
+ int index);
BT_HIDDEN
-struct bt_port *bt_component_add_port(
- struct bt_component *component,GPtrArray *ports,
- enum bt_port_type port_type, const char *name);
+struct bt_port *bt_component_get_input_port(struct bt_component *comp,
+ const char *name);
BT_HIDDEN
-enum bt_component_status bt_component_remove_port(
- struct bt_component *component, GPtrArray *ports,
+struct bt_port *bt_component_get_output_port(struct bt_component *comp,
const char *name);
+BT_HIDDEN
+struct bt_port *bt_component_add_input_port(
+ struct bt_component *component, const char *name);
+
+BT_HIDDEN
+struct bt_port *bt_component_add_output_port(
+ struct bt_component *component, const char *name);
+
+BT_HIDDEN
+enum bt_component_status bt_component_remove_port(
+ struct bt_component *component, struct bt_port *port);
+
#endif /* BABELTRACE_COMPONENT_COMPONENT_INTERNAL_H */
struct bt_component_sink {
struct bt_component parent;
- GPtrArray *input_ports;
-/* notification_mask_t registered_notifications_mask;*/
};
/**
struct bt_component *bt_component_sink_create(
struct bt_component_class *class, struct bt_value *params);
+BT_HIDDEN
+void bt_component_sink_destroy(struct bt_component *component);
+
/**
* Validate a sink component.
*
extern struct bt_port *bt_component_sink_add_input_port(
struct bt_component *component, const char *name);
/* Only allowed during the sink's initialization. */
-extern enum bt_component_status bt_component_sink_remove_input_port(
- struct bt_component *component, const char *name);
extern struct bt_port *bt_component_sink_get_default_input_port(
struct bt_component *component);
struct bt_component_source {
struct bt_component parent;
- GPtrArray *output_ports;
};
/**
struct bt_component *bt_component_source_create(
struct bt_component_class *class, struct bt_value *params);
+BT_HIDDEN
+void bt_component_source_destroy(struct bt_component *component);
+
/**
* Validate a source component.
*
/* Only allowed during the source's initialization. */
extern struct bt_port *bt_component_source_add_output_port(
struct bt_component *component, const char *name);
-/* Only allowed during the source's initialization. */
-extern enum bt_component_status bt_component_source_remove_output_port(
- struct bt_component *component, const char *name);
#ifdef __cplusplus
}
struct bt_component_graph;
struct bt_component;
struct bt_value;
+struct bt_port;
/**
* Status code. Errors are always negative.
*/
enum bt_component_status {
/** No error, okay. */
- BT_COMPONENT_STATUS_OK = 0,
+ BT_COMPONENT_STATUS_OK = 0,
/** No more work to be done by this component. **/
- BT_COMPONENT_STATUS_END = 1,
+ BT_COMPONENT_STATUS_END = 1,
/**
* Component can't process a notification at this time
* (e.g. would block), try again later.
*/
- BT_COMPONENT_STATUS_AGAIN = 2,
+ BT_COMPONENT_STATUS_AGAIN = 2,
+ /** Refuse port connection. */
+ BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION = 3,
/** General error. */
- BT_COMPONENT_STATUS_ERROR = -1,
+ BT_COMPONENT_STATUS_ERROR = -1,
/** Unsupported component feature. */
- BT_COMPONENT_STATUS_UNSUPPORTED = -2,
+ BT_COMPONENT_STATUS_UNSUPPORTED = -2,
/** Invalid arguments. */
- BT_COMPONENT_STATUS_INVALID = -3,
+ BT_COMPONENT_STATUS_INVALID = -3,
/** Memory allocation failure. */
- BT_COMPONENT_STATUS_NOMEM = -4,
+ BT_COMPONENT_STATUS_NOMEM = -4,
/** Element not found. */
- BT_COMPONENT_STATUS_NOT_FOUND = -5,
+ BT_COMPONENT_STATUS_NOT_FOUND = -5,
};
/**
* components.
*/
/* Downstream port. */
- struct bt_port *input_port;
+ struct bt_port *downstream_port;
/* Upstream port. */
- struct bt_port *output_port;
+ struct bt_port *upstream_port;
};
BT_HIDDEN
struct bt_connection *bt_connection_create(struct bt_graph *graph,
- struct bt_port *upstream, struct bt_port *downstream);
+ struct bt_port *upstream_port,
+ struct bt_port *downstream_port);
+
+BT_HIDDEN
+void bt_connection_disconnect_ports(struct bt_connection *conn,
+ struct bt_component *comp);
#endif /* BABELTRACE_COMPONENT_CONNECTION_INTERNAL_H */
struct bt_connection;
/* Returns the "downstream" input port. */
-extern struct bt_port *bt_connection_get_input_port(
+extern struct bt_port *bt_connection_get_downstream_port(
struct bt_connection *connection);
/* Returns the "upstream" output port. */
-extern struct bt_port *bt_connection_get_output_port(
+extern struct bt_port *bt_connection_get_upstream_port(
struct bt_connection *connection);
extern struct bt_notification_iterator *
struct bt_connection;
enum bt_graph_status {
+ /** No sink can consume at the moment. */
+ BT_GRAPH_STATUS_AGAIN = 2,
/** Downstream component does not support multiple inputs. */
BT_GRAPH_STATUS_END = 1,
BT_GRAPH_STATUS_OK = 0,
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);
* 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);
+extern enum bt_graph_status bt_graph_run(struct bt_graph *graph);
/**
* 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);
+extern enum bt_graph_status bt_graph_consume(struct bt_graph *graph);
#ifdef __cplusplus
}
struct bt_object base;
enum bt_port_type type;
GString *name;
- GPtrArray *connections;
- uint64_t max_connection_count;
+ struct bt_connection *connection;
};
BT_HIDDEN
enum bt_port_type type, const char *name);
BT_HIDDEN
-int bt_port_add_connection(struct bt_port *port,
+void bt_port_set_connection(struct bt_port *port,
struct bt_connection *connection);
#ifdef __cplusplus
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_connection *bt_port_get_connection(struct bt_port *port);
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);
+extern int bt_port_remove_from_component(struct bt_port *port);
+extern int bt_port_disconnect(struct bt_port *port);
+extern int bt_port_is_connected(struct bt_port *port);
#ifdef __cplusplus
}
/* Type of a component class attribute (internal use) */
enum __bt_plugin_component_class_descriptor_attribute_type {
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION = 0,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_HELP = 1,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INIT_METHOD = 2,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESTROY_METHOD = 3,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD = 4,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NEW_CONNECTION_METHOD = 5,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_INIT_METHOD = 6,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_DESTROY_METHOD = 7,
- BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_SEEK_TIME_METHOD = 8,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION = 0,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_HELP = 1,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INIT_METHOD = 2,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESTROY_METHOD = 3,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD = 4,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD = 5,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD = 6,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_INIT_METHOD = 7,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_DESTROY_METHOD = 8,
+ BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_SEEK_TIME_METHOD = 9,
};
/* Component class attribute (internal use) */
/* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD */
bt_component_class_query_method query_method;
- /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NEW_CONNECTION_METHOD */
- bt_component_class_new_connection_method new_connection_method;
+ /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD */
+ bt_component_class_accept_port_connection_method accept_port_connection_method;
+
+ /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD */
+ bt_component_class_port_disconnected_method port_disconnected_method;
/* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_INIT_METHOD */
bt_component_class_notification_iterator_init_method notif_iter_init_method;
__BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(query_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD, _id, _comp_class_id, sink, _x)
/*
- * Defines a new connection method attribute attached to a specific
+ * Defines an accept port connection method attribute attached to a
+ * specific source component class descriptor.
+ *
+ * _id: Plugin descriptor ID (C identifier).
+ * _comp_class_id: Component class descriptor ID (C identifier).
+ * _x: Accept port connection method
+ * (bt_component_class_accept_port_connection_method).
+ */
+#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \
+ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(accept_port_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD, _id, _comp_class_id, source, _x)
+
+/*
+ * Defines an accept port connection method attribute attached to a
+ * specific filter component class descriptor.
+ *
+ * _id: Plugin descriptor ID (C identifier).
+ * _comp_class_id: Component class descriptor ID (C identifier).
+ * _x: Accept port connection method
+ * (bt_component_class_accept_port_connection_method).
+ */
+#define BT_PLUGIN_FILTER_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \
+ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(accept_port_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD, _id, _comp_class_id, filter, _x)
+
+/*
+ * Defines an accept port connection method attribute attached to a
+ * specific sink component class descriptor.
+ *
+ * _id: Plugin descriptor ID (C identifier).
+ * _comp_class_id: Component class descriptor ID (C identifier).
+ * _x: Accept port connection method
+ * (bt_component_class_accept_port_connection_method).
+ */
+#define BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \
+ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(accept_port_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD, _id, _comp_class_id, sink, _x)
+
+/*
+ * Defines a port disconnected method attribute attached to a specific
* source component class descriptor.
*
* _id: Plugin descriptor ID (C identifier).
* _comp_class_id: Component class descriptor ID (C identifier).
- * _x: New connection method
- * (bt_component_class_new_connection_method).
+ * _x: Port disconnected method
+ * (bt_component_class_port_disconnected_method).
*/
-#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_NEW_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \
- __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(new_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NEW_CONNECTION_METHOD, _id, _comp_class_id, source, _x)
+#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \
+ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(port_disconnected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD, _id, _comp_class_id, source, _x)
/*
- * Defines a new connection method attribute attached to a specific
+ * Defines a port disconnected method attribute attached to a specific
* filter component class descriptor.
*
* _id: Plugin descriptor ID (C identifier).
* _comp_class_id: Component class descriptor ID (C identifier).
- * _x: New connection method
- * (bt_component_class_new_connection_method).
+ * _x: Port disconnected method
+ * (bt_component_class_port_disconnected_method).
*/
-#define BT_PLUGIN_FILTER_COMPONENT_CLASS_NEW_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \
- __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(new_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NEW_CONNECTION_METHOD, _id, _comp_class_id, filter, _x)
+#define BT_PLUGIN_FILTER_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \
+ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(port_disconnected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD, _id, _comp_class_id, filter, _x)
/*
- * Defines a new connection method attribute attached to a specific
+ * Defines a port disconnected method attribute attached to a specific
* sink component class descriptor.
*
* _id: Plugin descriptor ID (C identifier).
* _comp_class_id: Component class descriptor ID (C identifier).
- * _x: New connection method
- * (bt_component_class_new_connection_method).
+ * _x: Port disconnected method
+ * (bt_component_class_port_disconnected_method).
*/
-#define BT_PLUGIN_SINK_COMPONENT_CLASS_NEW_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \
- __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(new_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NEW_CONNECTION_METHOD, _id, _comp_class_id, sink, _x)
+#define BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \
+ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(port_disconnected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD, _id, _comp_class_id, sink, _x)
/*
* Defines an iterator initialization method attribute attached to a
BT_PLUGIN_SINK_COMPONENT_CLASS_QUERY_METHOD_WITH_ID(auto, _name, _x)
/*
- * Defines a new connection method attribute attached to a source component
- * class descriptor which is attached to the automatic plugin descriptor.
+ * Defines an accept port connection method attribute attached to a
+ * source component class descriptor which is attached to the automatic
+ * plugin descriptor.
+ *
+ * _name: Component class name (C identifier).
+ * _x: Accept port connection method
+ * (bt_component_class_accept_port_connection_method).
+ */
+#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(_name, _x) \
+ BT_PLUGIN_SOURCE_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(auto, _name, _x)
+
+/*
+ * Defines an accept port connection method attribute attached to a
+ * filter component class descriptor which is attached to the automatic
+ * plugin descriptor.
+ *
+ * _name: Component class name (C identifier).
+ * _x: Accept port connection method
+ * (bt_component_class_accept_port_connection_method).
+ */
+#define BT_PLUGIN_FILTER_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(_name, _x) \
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(auto, _name, _x)
+
+/*
+ * Defines an accept port connection method attribute attached to a sink
+ * component class descriptor which is attached to the automatic plugin
+ * descriptor.
+ *
+ * _name: Component class name (C identifier).
+ * _x: Accept port connection method
+ * (bt_component_class_accept_port_connection_method).
+ */
+#define BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(_name, _x) \
+ BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(auto, _name, _x)
+
+/*
+ * Defines a port disconnected method attribute attached to a source
+ * component class descriptor which is attached to the automatic plugin
+ * descriptor.
*
* _name: Component class name (C identifier).
- * _x: New connections method (bt_component_class_new_connection_method).
+ * _x: Port disconnected (bt_component_class_port_disconnected_method).
*/
-#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_NEW_CONNECTION_METHOD(_name, _x) \
- BT_PLUGIN_SOURCE_COMPONENT_CLASS_NEW_CONNECTION_METHOD_WITH_ID(auto, _name, _x)
+#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD(_name, _x) \
+ BT_PLUGIN_SOURCE_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD_WITH_ID(auto, _name, _x)
/*
- * Defines a new connection method attribute attached to a filter component
- * class descriptor which is attached to the automatic plugin descriptor.
+ * Defines a port disconnected method attribute attached to a filter
+ * component class descriptor which is attached to the automatic plugin
+ * descriptor.
*
* _name: Component class name (C identifier).
- * _x: New connections method (bt_component_class_new_connection_method).
+ * _x: Port disconnected (bt_component_class_port_disconnected_method).
*/
-#define BT_PLUGIN_FILTER_COMPONENT_CLASS_NEW_CONNECTION_METHOD(_name, _x) \
- BT_PLUGIN_FILTER_COMPONENT_CLASS_NEW_CONNECTION_METHOD_WITH_ID(auto, _name, _x)
+#define BT_PLUGIN_FILTER_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD(_name, _x) \
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD_WITH_ID(auto, _name, _x)
/*
- * Defines a new connection method attribute attached to a sink component
- * class descriptor which is attached to the automatic plugin descriptor.
+ * Defines a port disconnected method attribute attached to a sink
+ * component class descriptor which is attached to the automatic plugin
+ * descriptor.
*
* _name: Component class name (C identifier).
- * _x: New connections method (bt_component_class_new_connection_method).
+ * _x: Port disconnected (bt_component_class_port_disconnected_method).
*/
-#define BT_PLUGIN_SINK_COMPONENT_CLASS_NEW_CONNECTION_METHOD(_name, _x) \
- BT_PLUGIN_SINK_COMPONENT_CLASS_NEW_CONNECTION_METHOD_WITH_ID(auto, _name, _x)
+#define BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD(_name, _x) \
+ BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_DISCONNECTED_METHOD_WITH_ID(auto, _name, _x)
/*
* Defines an iterator initialization method attribute attached to a
return ret;
}
-int bt_component_class_set_new_connection_method(
+int bt_component_class_set_accept_port_connection_method(
struct bt_component_class *component_class,
- bt_component_class_new_connection_method new_connection_method)
+ bt_component_class_accept_port_connection_method method)
{
int ret = 0;
- if (!component_class || component_class->frozen ||
- !new_connection_method) {
+ if (!component_class || component_class->frozen || !method) {
+ ret = -1;
+ goto end;
+ }
+
+ component_class->methods.accept_port_connection = method;
+
+end:
+ return ret;
+}
+
+int bt_component_class_set_port_disconnected_method(
+ struct bt_component_class *component_class,
+ bt_component_class_port_disconnected_method method)
+{
+ int ret = 0;
+
+ if (!component_class || component_class->frozen || !method) {
ret = -1;
goto end;
}
- component_class->methods.new_connection_method = new_connection_method;
+ component_class->methods.port_disconnected = method;
end:
return ret;
#include <babeltrace/component/component-source-internal.h>
#include <babeltrace/component/component-filter-internal.h>
#include <babeltrace/component/component-sink-internal.h>
+#include <babeltrace/component/connection-internal.h>
#include <babeltrace/component/graph-internal.h>
#include <babeltrace/component/notification/iterator-internal.h>
#include <babeltrace/babeltrace-internal.h>
[BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
};
+static
+void (*component_destroy_funcs[])(struct bt_component *) = {
+ [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_destroy,
+ [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_destroy,
+ [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_destroy,
+};
+
static
enum bt_component_status (* const component_validation_funcs[])(
struct bt_component *) = {
component->destroy(component);
}
- g_string_free(component->name, TRUE);
- bt_put(component_class);
- g_free(component);
-}
-
-BT_HIDDEN
-enum bt_component_status bt_component_init(struct bt_component *component,
- bt_component_class_destroy_method destroy)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ if (component->input_ports) {
+ g_ptr_array_free(component->input_ports, TRUE);
+ }
- if (!component) {
- ret = BT_COMPONENT_STATUS_INVALID;
- goto end;
+ if (component->output_ports) {
+ g_ptr_array_free(component->output_ports, TRUE);
}
- component->initializing = true;
- component->destroy = destroy;
-end:
- return ret;
+ g_string_free(component->name, TRUE);
+ bt_put(component_class);
+ g_free(component);
}
enum bt_component_class_type bt_component_get_class_type(
return iterator;
}
+static
+struct bt_port *bt_component_add_port(
+ struct bt_component *component, GPtrArray *ports,
+ enum bt_port_type port_type, const char *name)
+{
+ size_t i;
+ struct bt_port *new_port = NULL;
+
+ if (!name || strlen(name) == 0) {
+ goto end;
+ }
+
+ /* Look for a port having the same name. */
+ for (i = 0; i < ports->len; i++) {
+ const char *port_name;
+ struct bt_port *port = g_ptr_array_index(
+ ports, i);
+
+ port_name = bt_port_get_name(port);
+ if (!port_name) {
+ continue;
+ }
+
+ if (!strcmp(name, port_name)) {
+ /* Port name clash, abort. */
+ goto end;
+ }
+ }
+
+ new_port = bt_port_create(component, port_type, name);
+ if (!new_port) {
+ goto end;
+ }
+
+ /*
+ * No name clash, add the port.
+ * The component is now the port's parent; it should _not_
+ * hold a reference to the port since the port's lifetime
+ * is now protected by the component's own lifetime.
+ */
+ g_ptr_array_add(ports, new_port);
+end:
+ return new_port;
+}
+
+BT_HIDDEN
+uint64_t bt_component_get_input_port_count(struct bt_component *comp)
+{
+ assert(comp);
+ return comp->input_ports->len;
+}
+
+BT_HIDDEN
+uint64_t bt_component_get_output_port_count(struct bt_component *comp)
+{
+ assert(comp);
+ return 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)
int ret;
struct bt_component *component = NULL;
enum bt_component_class_type type;
+ struct bt_port *default_port = NULL;
if (!component_class) {
goto end;
}
bt_object_init(component, bt_component_destroy);
+ component->class = bt_get(component_class);
+ component->destroy = component_destroy_funcs[type];
component->name = g_string_new(name);
if (!component->name) {
BT_PUT(component);
goto end;
}
+ component->input_ports = g_ptr_array_new_with_free_func(
+ bt_object_release);
+ if (!component->input_ports) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ component->output_ports = g_ptr_array_new_with_free_func(
+ bt_object_release);
+ if (!component->output_ports) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ if (type == BT_COMPONENT_CLASS_TYPE_SOURCE ||
+ type == BT_COMPONENT_CLASS_TYPE_FILTER) {
+ default_port = bt_component_add_port(component,
+ component->output_ports, BT_PORT_TYPE_OUTPUT,
+ DEFAULT_OUTPUT_PORT_NAME);
+ if (!default_port) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ BT_PUT(default_port);
+ }
+
+ if (type == BT_COMPONENT_CLASS_TYPE_FILTER ||
+ type == BT_COMPONENT_CLASS_TYPE_SINK) {
+ default_port = bt_component_add_port(component,
+ component->input_ports, BT_PORT_TYPE_INPUT,
+ DEFAULT_INPUT_PORT_NAME);
+ if (!default_port) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ BT_PUT(default_port);
+ }
+
+ component->initializing = true;
+
if (component_class->methods.init) {
ret = component_class->methods.init(component, params,
init_method_data);
bt_component_class_freeze(component->class);
end:
+ bt_put(default_port);
return component;
}
return (struct bt_graph *) bt_object_get_parent(&component->base);
}
-BT_HIDDEN
-int bt_component_init_input_ports(struct bt_component *component,
- GPtrArray **input_ports)
-{
- int ret = 0;
- struct bt_port *default_port;
-
- *input_ports = g_ptr_array_new_with_free_func(bt_object_release);
- if (!*input_ports) {
- ret = -1;
- goto end;
- }
-
- default_port = bt_component_add_port(component, *input_ports,
- BT_PORT_TYPE_INPUT, DEFAULT_INPUT_PORT_NAME);
- if (!default_port) {
- ret = -1;
- goto end;
- }
- bt_put(default_port);
-end:
- return ret;
-}
-
-BT_HIDDEN
-int bt_component_init_output_ports(struct bt_component *component,
- GPtrArray **output_ports)
-{
- int ret = 0;
- struct bt_port *default_port;
-
- *output_ports = g_ptr_array_new_with_free_func(bt_object_release);
- if (!*output_ports) {
- ret = -1;
- goto end;
- }
-
- default_port = bt_component_add_port(component, *output_ports,
- BT_PORT_TYPE_OUTPUT, DEFAULT_OUTPUT_PORT_NAME);
- if (!default_port) {
- ret = -1;
- goto end;
- }
- bt_put(default_port);
-end:
- return ret;
-}
-
-BT_HIDDEN
+static
struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name)
{
size_t i;
struct bt_port *ret_port = NULL;
+ assert(name);
+
for (i = 0; i < ports->len; i++) {
struct bt_port *port = g_ptr_array_index(ports, i);
const char *port_name = bt_port_get_name(port);
}
BT_HIDDEN
+struct bt_port *bt_component_get_input_port(struct bt_component *comp,
+ const char *name)
+{
+ assert(comp);
+
+ return bt_component_get_port(comp->input_ports, name);
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port(struct bt_component *comp,
+ const char *name)
+{
+ assert(comp);
+
+ return bt_component_get_port(comp->output_ports, name);
+}
+
+static
struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index)
{
struct bt_port *port = NULL;
}
BT_HIDDEN
-struct bt_port *bt_component_add_port(
- struct bt_component *component,GPtrArray *ports,
- enum bt_port_type port_type, const char *name)
+struct bt_port *bt_component_get_input_port_at_index(struct bt_component *comp,
+ int index)
{
- size_t i;
- struct bt_port *new_port = NULL;
+ assert(comp);
- if (!component->initializing || !name || *name == '\0') {
- goto end;
- }
+ return bt_component_get_port_at_index(comp->input_ports, index);
+}
- /* Look for a port having the same name. */
- for (i = 0; i < ports->len; i++) {
- const char *port_name;
- struct bt_port *port = g_ptr_array_index(
- ports, i);
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port_at_index(struct bt_component *comp,
+ int index)
+{
+ assert(comp);
- port_name = bt_port_get_name(port);
- if (!port_name) {
- continue;
- }
+ return bt_component_get_port_at_index(comp->output_ports, index);
+}
- if (!strcmp(name, port_name)) {
- /* Port name clash, abort. */
- goto end;
- }
- }
+BT_HIDDEN
+struct bt_port *bt_component_add_input_port(
+ struct bt_component *component, const char *name)
+{
+ return bt_component_add_port(component, component->input_ports,
+ BT_PORT_TYPE_INPUT, name);
+}
- new_port = bt_port_create(component, port_type, name);
- if (!new_port) {
- goto end;
+BT_HIDDEN
+struct bt_port *bt_component_add_output_port(
+ struct bt_component *component, const char *name)
+{
+ return bt_component_add_port(component, component->output_ports,
+ BT_PORT_TYPE_OUTPUT, name);
+}
+
+static
+void bt_component_remove_port_at_index(struct bt_component *component,
+ GPtrArray *ports, size_t index)
+{
+ struct bt_port *port;
+
+ assert(ports);
+ assert(index < ports->len);
+ port = g_ptr_array_index(ports, index);
+
+ /* Disconnect both ports of this port's connection, if any */
+ if (port->connection) {
+ bt_connection_disconnect_ports(port->connection, component);
}
- /*
- * No name clash, add the port.
- * The component is now the port's parent; it should _not_
- * hold a reference to the port since the port's lifetime
- * is now protected by the component's own lifetime.
- */
- g_ptr_array_add(ports, new_port);
-end:
- return new_port;
+ /* Remove from parent's array of ports (weak refs) */
+ g_ptr_array_remove_index(ports, index);
+
+ /* Detach port from its component parent */
+ BT_PUT(port->base.parent);
+
+ // TODO: notify graph user: component's port removed
}
BT_HIDDEN
enum bt_component_status bt_component_remove_port(
- struct bt_component *component, GPtrArray *ports,
- const char *name)
+ struct bt_component *component, struct bt_port *port)
{
size_t i;
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ GPtrArray *ports = NULL;
- if (!component->initializing || !name) {
+ if (!component || !port) {
status = BT_COMPONENT_STATUS_INVALID;
goto end;
}
- for (i = 0; i < ports->len; i++) {
- const char *port_name;
- struct bt_port *port = g_ptr_array_index(ports, i);
+ if (bt_port_get_type(port) == BT_PORT_TYPE_INPUT) {
+ ports = component->input_ports;
+ } else if (bt_port_get_type(port) == BT_PORT_TYPE_OUTPUT) {
+ ports = component->output_ports;
+ }
- port_name = bt_port_get_name(port);
- if (!port_name) {
- continue;
- }
+ assert(ports);
- if (!strcmp(name, port_name)) {
- g_ptr_array_remove_index(ports, i);
+ for (i = 0; i < ports->len; i++) {
+ struct bt_port *cur_port = g_ptr_array_index(ports, i);
+
+ if (cur_port == port) {
+ bt_component_remove_port_at_index(component,
+ ports, i);
goto end;
}
}
+
status = BT_COMPONENT_STATUS_NOT_FOUND;
end:
return status;
}
BT_HIDDEN
-enum bt_component_status bt_component_new_connection(
- struct bt_component *component, struct bt_port *own_port,
- struct bt_connection *connection)
+enum bt_component_status bt_component_accept_port_connection(
+ struct bt_component *comp, struct bt_port *port)
{
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- if (component->class->methods.new_connection_method) {
- status = component->class->methods.new_connection_method(
- own_port, connection);
+ assert(comp);
+ assert(port);
+
+ if (comp->class->methods.accept_port_connection) {
+ status = comp->class->methods.accept_port_connection(
+ comp, port);
}
return status;
}
+
+BT_HIDDEN
+void bt_component_port_disconnected(struct bt_component *comp,
+ struct bt_port *port)
+{
+ assert(comp);
+ assert(port);
+
+ if (comp->class->methods.port_disconnected) {
+ comp->class->methods.port_disconnected(comp, port);
+ }
+}
* SOFTWARE.
*/
+#include <babeltrace/component/component-internal.h>
+#include <babeltrace/component/component-source-internal.h>
+#include <babeltrace/component/component-filter-internal.h>
#include <babeltrace/component/connection-internal.h>
#include <babeltrace/component/graph-internal.h>
#include <babeltrace/component/port-internal.h>
-#include <babeltrace/component/component-source-internal.h>
-#include <babeltrace/component/component-filter-internal.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/compiler.h>
#include <glib.h>
BT_HIDDEN
struct bt_connection *bt_connection_create(
struct bt_graph *graph,
- struct bt_port *upstream, struct bt_port *downstream)
+ struct bt_port *upstream_port,
+ struct bt_port *downstream_port)
{
struct bt_connection *connection = NULL;
- if (bt_port_get_type(upstream) != BT_PORT_TYPE_OUTPUT) {
+ if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
goto end;
}
- if (bt_port_get_type(downstream) != BT_PORT_TYPE_INPUT) {
+ if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
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);
+ connection->upstream_port = upstream_port;
+ connection->downstream_port = downstream_port;
+ bt_port_set_connection(upstream_port, connection);
+ bt_port_set_connection(downstream_port, connection);
bt_object_set_parent(connection, &graph->base);
end:
return connection;
}
-struct bt_port *bt_connection_get_input_port(
+BT_HIDDEN
+void bt_connection_disconnect_ports(struct bt_connection *conn,
+ struct bt_component *acting_comp)
+{
+ struct bt_component *downstream_comp = NULL;
+ struct bt_component *upstream_comp = NULL;
+ struct bt_port *downstream_port = conn->downstream_port;
+ struct bt_port *upstream_port = conn->upstream_port;
+
+ if (downstream_port) {
+ downstream_comp = bt_port_get_component(downstream_port);
+ bt_port_set_connection(downstream_port, NULL);
+ conn->downstream_port = NULL;
+ }
+
+ if (upstream_port) {
+ upstream_comp = bt_port_get_component(upstream_port);
+ bt_port_set_connection(upstream_port, NULL);
+ conn->upstream_port = NULL;
+ }
+
+ if (downstream_comp && downstream_comp != acting_comp &&
+ downstream_comp->class->methods.port_disconnected) {
+ bt_component_port_disconnected(downstream_comp,
+ downstream_port);
+ }
+
+ if (upstream_comp && upstream_comp != acting_comp &&
+ upstream_comp->class->methods.port_disconnected) {
+ bt_component_port_disconnected(upstream_comp, upstream_port);
+ }
+
+ // TODO: notify graph user: component's port disconnected
+
+ bt_put(downstream_comp);
+ bt_put(upstream_comp);
+}
+
+struct bt_port *bt_connection_get_upstream_port(
struct bt_connection *connection)
{
- return connection ? bt_get(connection->input_port) : NULL;
+ return connection ? bt_get(connection->upstream_port) : NULL;
}
-struct bt_port *bt_connection_get_output_port(
+struct bt_port *bt_connection_get_downstream_port(
struct bt_connection *connection)
{
- return connection ? bt_get(connection->output_port) : NULL;
+ return connection ? bt_get(connection->downstream_port) : NULL;
}
struct bt_notification_iterator *
goto end;
}
- upstream_component = bt_port_get_component(connection->output_port);
+ if (!connection->upstream_port || !connection->downstream_port) {
+ goto end;
+ }
+
+ upstream_component = bt_port_get_component(connection->upstream_port);
assert(upstream_component);
switch (bt_component_get_class_type(upstream_component)) {
return bt_component_create_iterator(component, init_method_data);
}
-static
+BT_HIDDEN
void bt_component_filter_destroy(struct bt_component *component)
{
- struct bt_component_filter *filter = container_of(component,
- struct bt_component_filter, parent);
-
- if (filter->input_ports) {
- g_ptr_array_free(filter->input_ports, TRUE);
- }
-
- if (filter->output_ports) {
- g_ptr_array_free(filter->output_ports, TRUE);
- }
}
BT_HIDDEN
struct bt_component *bt_component_filter_create(
struct bt_component_class *class, struct bt_value *params)
{
- int ret;
struct bt_component_filter *filter = NULL;
- enum bt_component_status status;
filter = g_new0(struct bt_component_filter, 1);
if (!filter) {
goto end;
}
- filter->parent.class = bt_get(class);
- status = bt_component_init(&filter->parent, bt_component_filter_destroy);
- if (status != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-
- ret = bt_component_init_input_ports(&filter->parent,
- &filter->input_ports);
- if (ret) {
- goto error;
- }
-
- ret = bt_component_init_output_ports(&filter->parent,
- &filter->output_ports);
- if (ret) {
- goto error;
- }
-
end:
return filter ? &filter->parent : NULL;
-error:
- BT_PUT(filter);
- goto end;
}
BT_HIDDEN
struct bt_component *component, uint64_t *count)
{
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- struct bt_component_filter *filter;
- if (!component || !count) {
+ if (!component || !count ||
+ component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
status = BT_COMPONENT_STATUS_INVALID;
goto end;
}
- if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- filter = container_of(component, struct bt_component_filter, parent);
- *count = (uint64_t) filter->input_ports->len;
+ *count = bt_component_get_input_port_count(component);
end:
return status;
}
struct bt_port *bt_component_filter_get_input_port(
struct bt_component *component, const char *name)
{
- struct bt_component_filter *filter;
- struct bt_port *ret_port = NULL;
+ struct bt_port *port = NULL;
if (!component || !name ||
component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
goto end;
}
- filter = container_of(component, struct bt_component_filter, parent);
- ret_port = bt_component_get_port(filter->input_ports, name);
+ port = bt_component_get_input_port(component, name);
end:
- return ret_port;
+ return port;
}
struct bt_port *bt_component_filter_get_input_port_at_index(
struct bt_component *component, int index)
{
struct bt_port *port = NULL;
- struct bt_component_filter *filter;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
goto end;
}
- filter = container_of(component, struct bt_component_filter, parent);
- port = bt_component_get_port_at_index(filter->input_ports, index);
+ port = bt_component_get_input_port_at_index(component, index);
end:
return port;
}
struct bt_port *bt_component_filter_add_input_port(
struct bt_component *component, const char *name)
{
- struct bt_port *port;
- struct bt_component_filter *filter;
+ struct bt_port *port = NULL;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- port = NULL;
goto end;
}
- filter = container_of(component, struct bt_component_filter, parent);
- port = bt_component_add_port(component, filter->input_ports,
- BT_PORT_TYPE_INPUT, name);
+ port = bt_component_add_input_port(component, name);
end:
return port;
}
-enum bt_component_status bt_component_filter_remove_input_port(
- struct bt_component *component, const char *name)
-{
- enum bt_component_status status;
- struct bt_component_filter *filter;
-
- if (!component ||
- component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- filter = container_of(component, struct bt_component_filter, parent);
- status = bt_component_remove_port(component, filter->input_ports,
- name);
-end:
- return status;
-}
-
enum bt_component_status bt_component_filter_get_output_port_count(
struct bt_component *component, uint64_t *count)
{
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- struct bt_component_filter *filter;
- if (!component || !count) {
+ if (!component || !count ||
+ component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
status = BT_COMPONENT_STATUS_INVALID;
goto end;
}
- if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- filter = container_of(component, struct bt_component_filter, parent);
- *count = (uint64_t) filter->output_ports->len;
+ *count = bt_component_get_output_port_count(component);
end:
return status;
}
struct bt_port *bt_component_filter_get_output_port(
struct bt_component *component, const char *name)
{
- struct bt_component_filter *filter;
- struct bt_port *ret_port = NULL;
+ struct bt_port *port = NULL;
if (!component || !name ||
component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
goto end;
}
- filter = container_of(component, struct bt_component_filter, parent);
- ret_port = bt_component_get_port(filter->output_ports, name);
+ port = bt_component_get_output_port(component, name);
end:
- return ret_port;
+ return port;
}
struct bt_port *bt_component_filter_get_output_port_at_index(
struct bt_component *component, int index)
{
struct bt_port *port = NULL;
- struct bt_component_filter *filter;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
goto end;
}
- filter = container_of(component, struct bt_component_filter, parent);
- port = bt_component_get_port_at_index(filter->output_ports, index);
+ port = bt_component_get_output_port_at_index(component, index);
end:
return port;
}
struct bt_port *bt_component_filter_add_output_port(
struct bt_component *component, const char *name)
{
- struct bt_port *port;
- struct bt_component_filter *filter;
+ struct bt_port *port = NULL;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- port = NULL;
goto end;
}
- filter = container_of(component, struct bt_component_filter, parent);
- port = bt_component_add_port(component, filter->output_ports,
- BT_PORT_TYPE_OUTPUT, name);
+ port = bt_component_add_output_port(component, name);
end:
return port;
}
-
-enum bt_component_status bt_component_filter_remove_output_port(
- struct bt_component *component, const char *name)
-{
- enum bt_component_status status;
- struct bt_component_filter *filter;
-
- if (!component ||
- component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- filter = container_of(component, struct bt_component_filter, parent);
- status = bt_component_remove_port(component, filter->output_ports,
- name);
-end:
- return status;
-}
struct bt_graph *downstream_graph = NULL;
struct bt_component *upstream_component = NULL;
struct bt_component *downstream_component = NULL;
+ struct bt_connection *existing_conn = NULL;
enum bt_component_status component_status;
bool upstream_was_already_in_graph;
bool downstream_was_already_in_graph;
goto end;
}
+ /* Ensure appropriate types for upstream and downstream ports. */
if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
goto end;
}
goto end;
}
- /* Ensure the components are not already part of another graph. */
+ /* Ensure that both ports are currently unconnected. */
+ existing_conn = bt_port_get_connection(upstream_port);
+ bt_put(existing_conn);
+ if (existing_conn) {
+ fprintf(stderr, "Upstream port is already connected\n");
+ goto end;
+ }
+
+ existing_conn = bt_port_get_connection(downstream_port);
+ bt_put(existing_conn);
+ if (existing_conn) {
+ fprintf(stderr, "Downstream port is already connected\n");
+ goto end;
+ }
+
+ /*
+ * Ensure that both ports are still attached to their creating
+ * component.
+ */
upstream_component = bt_port_get_component(upstream_port);
- assert(upstream_component);
+ if (!upstream_component) {
+ fprintf(stderr, "Upstream port does not belong to a component\n");
+ goto end;
+ }
+
+ downstream_component = bt_port_get_component(downstream_port);
+ if (!downstream_component) {
+ fprintf(stderr, "Downstream port does not belong to a component\n");
+ goto end;
+ }
+
+ /* Ensure the components are not already part of another graph. */
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;
}
upstream_was_already_in_graph = (graph == upstream_graph);
-
- 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");
}
/*
- * Ownership of up/downstream_component and of the connection object is
- * transferred to the graph.
+ * Ownership of upstream_component/downstream_component and of
+ * the connection object is transferred to the graph.
*/
g_ptr_array_add(graph->connections, connection);
*/
/*
- * 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.
+ * The components and connection are added to the graph before
+ * invoking the `accept_port_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);
+ component_status = bt_component_accept_port_connection(
+ upstream_component, upstream_port);
if (component_status != BT_COMPONENT_STATUS_OK) {
goto error_rollback;
}
- component_status = bt_component_new_connection(downstream_component,
- downstream_port, connection);
+ component_status = bt_component_accept_port_connection(
+ downstream_component, downstream_port);
if (component_status != BT_COMPONENT_STATUS_OK) {
goto error_rollback;
}
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)
/* 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);
+ origin_port = bt_component_get_input_port_at_index(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) {
+ new_port = bt_component_get_input_port_at_index(new_component,
+ port_index);
+ if (!new_port) {
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);
+ origin_connection = bt_port_get_connection(origin_port);
+ if (origin_connection) {
+ upstream_port = bt_connection_get_upstream_port(
+ origin_connection);
if (!upstream_port) {
goto error_disconnect;
}
if (!new_connection) {
goto error_disconnect;
}
-
- BT_PUT(upstream_port);
- BT_PUT(origin_connection);
- BT_PUT(new_connection);
}
+
+ 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);
+ for (port_index = 0; port_index < origin_output_port_count; port_index++) {
+ origin_port = bt_component_get_output_port_at_index(origin,
+ port_index);
if (!origin_port) {
status = BT_GRAPH_STATUS_ERROR;
goto error_disconnect;
}
- new_port = get_output_port(new_component, port_index);
+ new_port = bt_component_get_output_port_at_index(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 = bt_port_get_connection(origin_port);
+ if (origin_connection) {
+ downstream_port = bt_connection_get_downstream_port(
origin_connection);
if (!downstream_port) {
goto error_disconnect;
if (!new_connection) {
goto error_disconnect;
}
-
- BT_PUT(downstream_port);
- BT_PUT(origin_connection);
- BT_PUT(new_connection);
}
+
+ BT_PUT(downstream_port);
+ BT_PUT(origin_connection);
+ BT_PUT(new_connection);
BT_PUT(origin_port);
BT_PUT(new_port);
}
goto end;
}
-enum bt_component_status bt_graph_consume(struct bt_graph *graph)
+enum bt_graph_status bt_graph_consume(struct bt_graph *graph)
{
struct bt_component *sink;
- enum bt_component_status status;
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+ enum bt_component_status comp_status;
GList *current_node;
if (!graph) {
- status = BT_COMPONENT_STATUS_INVALID;
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (g_queue_is_empty(graph->sinks_to_consume)) {
- status = BT_COMPONENT_STATUS_END;
+ status = BT_GRAPH_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) {
+ comp_status = bt_component_sink_consume(sink);
+ switch (comp_status) {
+ case BT_COMPONENT_STATUS_OK:
+ break;
+ case BT_COMPONENT_STATUS_END:
+ status = BT_GRAPH_STATUS_END;
+ break;
+ case BT_COMPONENT_STATUS_AGAIN:
+ status = BT_GRAPH_STATUS_AGAIN;
+ break;
+ case BT_COMPONENT_STATUS_INVALID:
+ status = BT_GRAPH_STATUS_INVALID;
+ break;
+ default:
+ status = BT_GRAPH_STATUS_ERROR;
+ break;
+ }
+
+ if (status != BT_GRAPH_STATUS_END) {
g_queue_push_tail_link(graph->sinks_to_consume, current_node);
goto end;
}
return status;
}
-enum bt_graph_status bt_graph_run(struct bt_graph *graph,
- enum bt_component_status *_component_status)
+enum bt_graph_status bt_graph_run(struct bt_graph *graph)
{
- enum bt_component_status component_status;
- enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
if (!graph) {
- graph_status = BT_GRAPH_STATUS_INVALID;
+ status = BT_GRAPH_STATUS_INVALID;
goto error;
}
do {
- component_status = bt_graph_consume(graph);
- if (component_status == BT_COMPONENT_STATUS_AGAIN) {
+ status = bt_graph_consume(graph);
+ if (status == BT_GRAPH_STATUS_AGAIN) {
/*
* If AGAIN is received and there are multiple sinks,
* go ahead and consume from the next sink.
* time.
*/
if (graph->sinks_to_consume->length > 1) {
- component_status = BT_COMPONENT_STATUS_OK;
+ status = BT_GRAPH_STATUS_OK;
}
}
- } while (component_status == BT_COMPONENT_STATUS_OK);
-
- if (_component_status) {
- *_component_status = component_status;
- }
+ } while (status == BT_GRAPH_STATUS_OK);
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;
+ status = BT_GRAPH_STATUS_END;
}
error:
- return graph_status;
+ return status;
}
#include <babeltrace/component/component-internal.h>
#include <babeltrace/component/port-internal.h>
+#include <babeltrace/component/connection-internal.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/compiler.h>
if (port->name) {
g_string_free(port->name, TRUE);
}
- if (port->connections) {
- g_ptr_array_free(port->connections, TRUE);
- }
g_free(port);
}
struct bt_port *bt_port_create(struct bt_component *parent_component,
enum bt_port_type type, const char *name)
{
- struct bt_port *port;
+ struct bt_port *port = NULL;
assert(name);
assert(parent_component);
assert(type == BT_PORT_TYPE_INPUT || type == BT_PORT_TYPE_OUTPUT);
- if (*name == '\0') {
- port = NULL;
+ if (strlen(name) == 0) {
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 ? 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 *bt_port_get_connection(struct bt_port *port)
{
- struct bt_connection *connection;
+ struct bt_connection *connection = NULL;
- if (!port || index < 0 || index >= port->connections->len) {
- connection = NULL;
+ if (!port || !port->connection) {
goto end;
}
- connection = bt_get(g_ptr_array_index(port->connections, index));
+ connection = bt_get(port->connection);
end:
return connection;
}
}
BT_HIDDEN
-int bt_port_add_connection(struct bt_port *port,
+void bt_port_set_connection(struct bt_port *port,
struct bt_connection *connection)
+{
+ /*
+ * Don't take a reference on connection as its existence is
+ * guaranteed by the existence of the graph in which the
+ * connection exists.
+ */
+ port->connection = connection;
+}
+
+int bt_port_remove_from_component(struct bt_port *port)
{
int ret = 0;
+ struct bt_component *comp = NULL;
- if (port->connections->len == port->max_connection_count) {
+ if (!port) {
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);
+ comp = (void *) bt_object_get_parent(port);
+ ret = bt_component_remove_port(comp, port);
+
end:
+ bt_put(comp);
return ret;
}
-enum bt_port_status bt_port_get_maximum_connection_count(
- struct bt_port *port, uint64_t *count)
+int bt_port_disconnect(struct bt_port *port)
{
- enum bt_port_status status = BT_PORT_STATUS_OK;
+ int ret = 0;
- if (!port || !count) {
- status = BT_PORT_STATUS_INVALID;
+ if (!port) {
+ ret = -1;
goto end;
}
- *count = port->max_connection_count;
+ if (port->connection) {
+ bt_connection_disconnect_ports(port->connection, NULL);
+ }
+
end:
- return status;
+ return ret;
}
-enum bt_port_status bt_port_set_maximum_connection_count(
- struct bt_port *port, uint64_t count)
+int bt_port_is_connected(struct bt_port *port)
{
- enum bt_port_status status = BT_PORT_STATUS_OK;
+ int ret;
- if (!port || count < port->connections->len || count == 0) {
- status = BT_PORT_STATUS_INVALID;
+ if (!port) {
+ ret = -1;
goto end;
}
- port->max_connection_count = count;
+ ret = port->connection ? 1 : 0;
+
end:
- return status;
+ return ret;
}
return ret;
}
-static
+BT_HIDDEN
void bt_component_sink_destroy(struct bt_component *component)
{
- struct bt_component_sink *sink = container_of(component,
- struct bt_component_sink, parent);
-
- if (sink->input_ports) {
- g_ptr_array_free(sink->input_ports, TRUE);
- }
}
BT_HIDDEN
struct bt_component_class *class, struct bt_value *params)
{
struct bt_component_sink *sink = NULL;
- enum bt_component_status ret;
sink = g_new0(struct bt_component_sink, 1);
if (!sink) {
goto end;
}
- sink->parent.class = bt_get(class);
- ret = bt_component_init(&sink->parent, bt_component_sink_destroy);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-
-/*
- ret = bt_component_sink_register_notification_type(&sink->parent,
- BT_NOTIFICATION_TYPE_EVENT);
- if (ret != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-*/
- ret = bt_component_init_input_ports(&sink->parent,
- &sink->input_ports);
- if (ret) {
- goto error;
- }
-
end:
return sink ? &sink->parent : NULL;
-error:
- BT_PUT(sink);
- return NULL;
}
BT_HIDDEN
end:
return ret;
}
-/*
-static
-enum bt_component_status bt_component_sink_register_notification_type(
- struct bt_component *component, enum bt_notification_type type)
-{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_component_sink *sink = NULL;
-
- if (!component) {
- ret = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) {
- ret = BT_COMPONENT_STATUS_UNSUPPORTED;
- goto end;
- }
-
- if (type <= BT_NOTIFICATION_TYPE_UNKNOWN ||
- type >= BT_NOTIFICATION_TYPE_NR) {
- ret = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
- sink = container_of(component, struct bt_component_sink, parent);
- if (type == BT_NOTIFICATION_TYPE_ALL) {
- sink->registered_notifications_mask = ~(notification_mask_t) 0;
- } else {
- sink->registered_notifications_mask |=
- (notification_mask_t) 1 << type;
- }
-end:
- return ret;
-}
-*/
enum bt_component_status bt_component_sink_get_input_port_count(
struct bt_component *component, uint64_t *count)
{
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- struct bt_component_sink *sink;
- if (!component || !count) {
+ if (!component || !count ||
+ component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
status = BT_COMPONENT_STATUS_INVALID;
goto end;
}
- if (component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- sink = container_of(component, struct bt_component_sink, parent);
- *count = (uint64_t) sink->input_ports->len;
+ *count = bt_component_get_input_port_count(component);
end:
return status;
}
struct bt_port *bt_component_sink_get_input_port(
struct bt_component *component, const char *name)
{
- struct bt_component_sink *sink;
- struct bt_port *ret_port = NULL;
+ struct bt_port *port = NULL;
if (!component || !name ||
component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
goto end;
}
- sink = container_of(component, struct bt_component_sink, parent);
- ret_port = bt_component_get_port(sink->input_ports, name);
+ port = bt_component_get_input_port(component, name);
end:
- return ret_port;
+ return port;
}
struct bt_port *bt_component_sink_get_input_port_at_index(
struct bt_component *component, int index)
{
struct bt_port *port = NULL;
- struct bt_component_sink *sink;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
goto end;
}
- sink = container_of(component, struct bt_component_sink, parent);
- port = bt_component_get_port_at_index(sink->input_ports, index);
+ port = bt_component_get_input_port_at_index(component, index);
end:
return port;
}
struct bt_port *bt_component_sink_add_input_port(
struct bt_component *component, const char *name)
{
- struct bt_port *port;
- struct bt_component_sink *sink;
+ struct bt_port *port = NULL;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
- port = NULL;
goto end;
}
- sink = container_of(component, struct bt_component_sink, parent);
- port = bt_component_add_port(component, sink->input_ports,
- BT_PORT_TYPE_INPUT, name);
+ port = bt_component_add_input_port(component, name);
end:
return port;
}
-
-enum bt_component_status bt_component_sink_remove_input_port(
- struct bt_component *component, const char *name)
-{
- enum bt_component_status status;
- struct bt_component_sink *sink;
-
- if (!component ||
- component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- sink = container_of(component, struct bt_component_sink, parent);
- status = bt_component_remove_port(component, sink->input_ports,
- name);
-end:
- return status;
-}
return ret;
}
-static
+BT_HIDDEN
void bt_component_source_destroy(struct bt_component *component)
{
- struct bt_component_source *source = container_of(component,
- struct bt_component_source, parent);
-
- if (source->output_ports) {
- g_ptr_array_free(source->output_ports, TRUE);
- }
}
-
BT_HIDDEN
struct bt_component *bt_component_source_create(
struct bt_component_class *class, struct bt_value *params)
{
- int ret;
struct bt_component_source *source = NULL;
- enum bt_component_status status;
source = g_new0(struct bt_component_source, 1);
if (!source) {
goto end;
}
- source->parent.class = bt_get(class);
- status = bt_component_init(&source->parent, bt_component_source_destroy);
- if (status != BT_COMPONENT_STATUS_OK) {
- goto error;
- }
-
- ret = bt_component_init_output_ports(&source->parent, &source->output_ports);
- if (ret) {
- goto error;
- }
-
end:
return source ? &source->parent : NULL;
-error:
- BT_PUT(source);
- goto end;
}
BT_HIDDEN
struct bt_component *component, uint64_t *count)
{
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- struct bt_component_source *source;
- if (!component || !count) {
+ if (!component || !count ||
+ component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
status = BT_COMPONENT_STATUS_INVALID;
goto end;
}
- if (component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- source = container_of(component, struct bt_component_source, parent);
- *count = (uint64_t) source->output_ports->len;
+ *count = bt_component_get_output_port_count(component);
end:
return status;
}
struct bt_port *bt_component_source_get_output_port(
struct bt_component *component, const char *name)
{
- struct bt_component_source *source;
- struct bt_port *ret_port = NULL;
+ struct bt_port *port = NULL;
if (!component || !name ||
component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
goto end;
}
- source = container_of(component, struct bt_component_source, parent);
- ret_port = bt_component_get_port(source->output_ports, name);
+ port = bt_component_get_output_port(component, name);
end:
- return ret_port;
+ return port;
}
struct bt_port *bt_component_source_get_output_port_at_index(
struct bt_component *component, int index)
{
struct bt_port *port = NULL;
- struct bt_component_source *source;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
goto end;
}
- source = container_of(component, struct bt_component_source, parent);
- port = bt_component_get_port_at_index(source->output_ports, index);
+ port = bt_component_get_output_port_at_index(component, index);
end:
return port;
}
struct bt_port *bt_component_source_add_output_port(
struct bt_component *component, const char *name)
{
- struct bt_port *port;
- struct bt_component_source *source;
+ struct bt_port *port = NULL;
if (!component ||
component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
- port = NULL;
goto end;
}
- source = container_of(component, struct bt_component_source, parent);
- port = bt_component_add_port(component, source->output_ports,
- BT_PORT_TYPE_OUTPUT, name);
+ port = bt_component_add_output_port(component, name);
end:
return port;
}
-
-enum bt_component_status bt_component_source_remove_output_port(
- struct bt_component *component, const char *name)
-{
- enum bt_component_status status;
- struct bt_component_source *source;
-
- if (!component ||
- component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- source = container_of(component, struct bt_component_source, parent);
- status = bt_component_remove_port(component, source->output_ports,
- name);
-end:
- return status;
-}
bt_component_class_init_method init_method;
bt_component_class_destroy_method destroy_method;
bt_component_class_query_method query_method;
- bt_component_class_new_connection_method new_connection_method;
+ bt_component_class_accept_port_connection_method accept_port_connection_method;
+ bt_component_class_port_disconnected_method port_disconnected_method;
struct bt_component_class_iterator_methods iterator_methods;
};
cc_full_descr->query_method =
cur_cc_descr_attr->value.query_method;
break;
- case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NEW_CONNECTION_METHOD:
- cc_full_descr->new_connection_method =
- cur_cc_descr_attr->value.new_connection_method;
+ case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD:
+ cc_full_descr->accept_port_connection_method =
+ cur_cc_descr_attr->value.accept_port_connection_method;
+ break;
+ case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD:
+ cc_full_descr->port_disconnected_method =
+ cur_cc_descr_attr->value.port_disconnected_method;
break;
case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_INIT_METHOD:
cc_full_descr->iterator_methods.init =
}
}
- if (cc_full_descr->new_connection_method) {
- ret = bt_component_class_set_new_connection_method(
- comp_class, cc_full_descr->new_connection_method);
+ if (cc_full_descr->accept_port_connection_method) {
+ ret = bt_component_class_set_accept_port_connection_method(
+ comp_class, cc_full_descr->accept_port_connection_method);
+ if (ret) {
+ status = BT_PLUGIN_STATUS_ERROR;
+ BT_PUT(comp_class);
+ goto end;
+ }
+ }
+
+ if (cc_full_descr->port_disconnected_method) {
+ ret = bt_component_class_set_port_disconnected_method(
+ comp_class, cc_full_descr->port_disconnected_method);
if (ret) {
status = BT_PLUGIN_STATUS_ERROR;
BT_PUT(comp_class);
}
static
-enum bt_component_status text_new_connection(struct bt_port *own_port,
- struct bt_connection *connection)
+enum bt_component_status text_accept_port_connection(struct bt_component *component,
+ struct bt_port *self_port)
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_component *component;
+ struct bt_connection *connection;
struct text_component *text;
- component = bt_port_get_component(own_port);
- assert(component);
text = bt_component_get_private_data(component);
assert(text);
assert(!text->input_iterator);
+ connection = bt_port_get_connection(self_port);
+ assert(connection);
text->input_iterator = bt_connection_create_notification_iterator(
connection);
if (!text->input_iterator) {
ret = BT_COMPONENT_STATUS_ERROR;
}
- bt_put(component);
+
+ bt_put(connection);
return ret;
}
goto end;
}
- ret = bt_value_string_get(color_value, &color);
- if (ret) {
+ status = bt_value_string_get(color_value, &color);
+ if (status) {
warn_wrong_color_param(text);
} else {
if (strcmp(color, "never") == 0) {
BT_PLUGIN_LICENSE("MIT");
BT_PLUGIN_SINK_COMPONENT_CLASS(text, run);
BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(text, text_component_init);
-BT_PLUGIN_SINK_COMPONENT_CLASS_NEW_CONNECTION_METHOD(text, text_new_connection);
+BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(text, text_accept_port_connection);
BT_PLUGIN_SINK_COMPONENT_CLASS_DESTROY_METHOD(text, destroy_text);
BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(text,
"Formats CTF-IR to text. Formerly known as ctf-text.");
return ret;
}
-enum bt_component_status dummy_new_connection(struct bt_port *own_port,
- struct bt_connection *connection)
+enum bt_component_status dummy_accept_port_connection(struct bt_component *component,
+ struct bt_port *self_port)
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_component *component;
struct dummy *dummy;
+ struct bt_connection *connection;
struct bt_notification_iterator *iterator;
- component = bt_port_get_component(own_port);
- assert(component);
-
dummy = bt_component_get_private_data(component);
assert(dummy);
+ connection = bt_port_get_connection(self_port);
+ assert(connection);
+
iterator = bt_connection_create_notification_iterator(connection);
if (!iterator) {
ret = BT_COMPONENT_STATUS_ERROR;
g_ptr_array_add(dummy->iterators, iterator);
end:
- bt_put(component);
+ bt_put(connection);
return ret;
}
enum bt_component_status dummy_init(struct bt_component *component,
struct bt_value *params, void *init_method_data);
void dummy_destroy(struct bt_component *component);
-enum bt_component_status dummy_new_connection(struct bt_port *own_port,
- struct bt_connection *connection);
+enum bt_component_status dummy_accept_port_connection(
+ struct bt_component *component,
+ struct bt_port *own_port);
enum bt_component_status dummy_consume(struct bt_component *component);
#endif /* BABELTRACE_PLUGINS_UTILS_DUMMY_H */
BT_PLUGIN_SINK_COMPONENT_CLASS(dummy, dummy_consume);
BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(dummy, dummy_init);
BT_PLUGIN_SINK_COMPONENT_CLASS_DESTROY_METHOD(dummy, dummy_destroy);
-BT_PLUGIN_SINK_COMPONENT_CLASS_NEW_CONNECTION_METHOD(dummy, dummy_new_connection);
+BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(dummy, dummy_accept_port_connection);
BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(dummy,
"Dummy sink component class: does absolutely nothing!");
/* Create a new iterator on the upstream component. */
input_port = bt_component_filter_get_default_input_port(component);
assert(input_port);
- connection = bt_port_get_connection(input_port, 0);
+ connection = bt_port_get_connection(input_port);
assert(connection);
it_data->input_iterator = bt_connection_create_notification_iterator(
enum bt_notification_iterator_status trimmer_iterator_seek_time(
struct bt_notification_iterator *iterator, int64_t time)
{
- enum bt_notification_iterator_status ret;
-
- ret = BT_NOTIFICATION_ITERATOR_STATUS_OK;
-end:
- return ret;
+ return BT_NOTIFICATION_ITERATOR_STATUS_OK;
}
}
static
-enum bt_component_status writer_component_new_connection(
- struct bt_port *own_port, struct bt_connection *connection)
+enum bt_component_status writer_component_accept_port_connection(
+ struct bt_component *component, struct bt_port *self_port)
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- struct bt_component *component;
+ struct bt_connection *connection;
struct writer_component *writer;
- component = bt_port_get_component(own_port);
- assert(component);
writer = bt_component_get_private_data(component);
assert(writer);
assert(!writer->input_iterator);
+ connection = bt_port_get_connection(self_port);
+ assert(connection);
writer->input_iterator = bt_connection_create_notification_iterator(
connection);
if (!writer->input_iterator) {
ret = BT_COMPONENT_STATUS_ERROR;
}
- bt_put(component);
+ bt_put(connection);
return ret;
}
enum bt_component_status run(struct bt_component *component)
{
enum bt_component_status ret;
+ enum bt_notification_iterator_status it_status;
struct bt_notification *notification = NULL;
struct bt_notification_iterator *it;
struct writer_component *writer_component =
goto end;
}
- ret = bt_notification_iterator_next(it);
- if (ret != BT_COMPONENT_STATUS_OK) {
+ it_status = bt_notification_iterator_next(it);
+ if (it_status != BT_COMPONENT_STATUS_OK) {
+ ret = BT_COMPONENT_STATUS_ERROR;
goto end;
}
BT_PLUGIN_LICENSE("MIT");
BT_PLUGIN_SINK_COMPONENT_CLASS(writer, run);
BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(writer, writer_component_init);
-BT_PLUGIN_SINK_COMPONENT_CLASS_NEW_CONNECTION_METHOD(writer,
- writer_component_new_connection);
+BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(writer,
+ writer_component_accept_port_connection);
BT_PLUGIN_SINK_COMPONENT_CLASS_DESTROY_METHOD(writer, destroy_writer_component);
BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(writer, "Formats CTF-IR to CTF.");