X-Git-Url: https://git.efficios.com/?a=blobdiff_plain;f=lib%2Fgraph%2Fcomponent.c;h=7bca1bfd7ef542fcc50aea65094c2c48fece7cbb;hb=d94d92ac6656fd252a5d7bb4f6c76935ba18e62e;hp=6da601c89295975edc8a86228b35fed59408c4af;hpb=28e6ca8b6e08d1cdd1af81ae819aa39baa206eaf;p=babeltrace.git diff --git a/lib/graph/component.c b/lib/graph/component.c index 6da601c8..7bca1bfd 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -25,18 +25,17 @@ #define BT_LOG_TAG "COMP" #include -#include +#include #include #include #include #include #include #include -#include #include #include #include -#include +#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #include @@ -63,10 +63,51 @@ void (*component_destroy_funcs[])(struct bt_component *) = { }; static -void bt_component_destroy(struct bt_object *obj) +void finalize_component(struct bt_component *comp) +{ + typedef void (*method_t)(void *); + + method_t method = NULL; + + BT_ASSERT(comp); + + switch (comp->class->type) { + case BT_COMPONENT_CLASS_TYPE_SOURCE: + { + struct bt_component_class_source *src_cc = (void *) comp->class; + + method = (method_t) src_cc->methods.finalize; + break; + } + case BT_COMPONENT_CLASS_TYPE_FILTER: + { + struct bt_component_class_filter *flt_cc = (void *) comp->class; + + method = (method_t) flt_cc->methods.finalize; + break; + } + case BT_COMPONENT_CLASS_TYPE_SINK: + { + struct bt_component_class_sink *sink_cc = (void *) comp->class; + + method = (method_t) sink_cc->methods.finalize; + break; + } + default: + abort(); + } + + if (method) { + BT_LIB_LOGD("Calling user's finalization method: " + "%![comp-]+c", comp); + method(comp); + } +} + +static +void destroy_component(struct bt_object *obj) { struct bt_component *component = NULL; - struct bt_component_class *component_class = NULL; int i; if (!obj) { @@ -77,16 +118,16 @@ void bt_component_destroy(struct bt_object *obj) * The component's reference count is 0 if we're here. Increment * it to avoid a double-destroy (possibly infinitely recursive). * This could happen for example if the component's finalization - * function does bt_object_get_ref() (or anything that causes bt_object_get_ref() to - * be called) on itself (ref. count goes from 0 to 1), and then - * bt_object_put_ref(): the reference count would go from 1 to 0 again and - * this function would be called again. + * function does bt_object_get_ref() (or anything that causes + * bt_object_get_ref() to be called) on itself (ref. count goes + * from 0 to 1), and then bt_object_put_ref(): the reference + * count would go from 1 to 0 again and this function would be + * called again. */ obj->ref_count++; component = container_of(obj, struct bt_component, base); - BT_LOGD("Destroying component: addr=%p, name=\"%s\", graph-addr=%p", - component, bt_component_get_name(component), - obj->parent); + BT_LIB_LOGD("Destroying component: %![comp-]+c, %![graph-]+g", + component, bt_component_borrow_graph(component)); /* Call destroy listeners in reverse registration order */ BT_LOGD_STR("Calling destroy listeners."); @@ -99,17 +140,13 @@ void bt_component_destroy(struct bt_object *obj) listener->func(component, listener->data); } - component_class = component->class; - /* * 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->initialized && component->class->methods.finalize) { - BT_LOGD_STR("Calling user's finalization method."); - component->class->methods.finalize( - bt_private_component_from_component(component)); + if (component->initialized) { + finalize_component(component); } if (component->destroy) { @@ -120,81 +157,62 @@ void bt_component_destroy(struct bt_object *obj) if (component->input_ports) { BT_LOGD_STR("Destroying input ports."); g_ptr_array_free(component->input_ports, TRUE); + component->input_ports = NULL; } if (component->output_ports) { BT_LOGD_STR("Destroying output ports."); g_ptr_array_free(component->output_ports, TRUE); + component->output_ports = NULL; } if (component->destroy_listeners) { g_array_free(component->destroy_listeners, TRUE); + component->destroy_listeners = NULL; } if (component->name) { g_string_free(component->name, TRUE); + component->name = NULL; } - BT_LOGD("Putting component class."); - bt_object_put_ref(component_class); + BT_LOGD_STR("Putting component class."); + BT_OBJECT_PUT_REF_AND_RESET(component->class); g_free(component); } -struct bt_component *bt_component_borrow_from_private( - struct bt_private_component *private_component) -{ - return (void *) private_component; -} - enum bt_component_class_type bt_component_get_class_type( struct bt_component *component) { - return component ? component->class->type : BT_COMPONENT_CLASS_TYPE_UNKNOWN; + BT_ASSERT_PRE_NON_NULL(component, "Component"); + return component->class->type; } static -struct bt_port *bt_component_add_port( +struct bt_port *add_port( struct bt_component *component, GPtrArray *ports, enum bt_port_type port_type, const char *name, void *user_data) { - size_t i; struct bt_port *new_port = NULL; struct bt_graph *graph = NULL; - if (!name) { - BT_LOGW_STR("Invalid parameter: name is NULL."); - goto end; - } + BT_ASSERT_PRE_NON_NULL(component, "Component"); + BT_ASSERT_PRE_NON_NULL(name, "Name"); + BT_ASSERT_PRE(strlen(name) > 0, "Name is empty"); + graph = bt_component_borrow_graph(component); + BT_ASSERT_PRE(graph && !bt_graph_is_canceled(graph), + "Component's graph is canceled: %![comp-]+c, %![graph-]+g", + component, graph); - if (strlen(name) == 0) { - BT_LOGW_STR("Invalid parameter: name is an empty string."); - goto end; - } + // TODO: Validate that the name is not already used. - BT_LOGD("Adding port to component: comp-addr=%p, comp-name=\"%s\", " + BT_LIB_LOGD("Adding port to component: %![comp-]+c, " "port-type=%s, port-name=\"%s\"", component, - bt_component_get_name(component), bt_port_type_string(port_type), name); - /* 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); - BT_ASSERT(port_name); - - if (!strcmp(name, port_name)) { - /* Port name clash, abort. */ - BT_LOGW("Invalid parameter: another port with the same name already exists in the component: " - "other-port-addr=%p", port); - goto end; - } - } - new_port = bt_port_create(component, port_type, name, user_data); if (!new_port) { - BT_LOGE("Cannot create port object."); + BT_LOGE_STR("Cannot create port object."); goto end; } @@ -215,35 +233,32 @@ struct bt_port *bt_component_add_port( BT_OBJECT_PUT_REF_AND_RESET(graph); } - BT_LOGD("Created and added port to component: comp-addr=%p, comp-name=\"%s\", " - "port-type=%s, port-name=\"%s\", port-addr=%p", component, - bt_component_get_name(component), - bt_port_type_string(port_type), name, new_port); + BT_LIB_LOGD("Created and added port to component: " + "%![comp-]+c, %![port-]+p", component, new_port); end: return new_port; } BT_HIDDEN -int64_t bt_component_get_input_port_count(struct bt_component *comp) +uint64_t bt_component_get_input_port_count(struct bt_component *comp) { - BT_ASSERT(comp); - return (int64_t) comp->input_ports->len; + BT_ASSERT_PRE_NON_NULL(comp, "Component"); + return (uint64_t) comp->input_ports->len; } BT_HIDDEN -int64_t bt_component_get_output_port_count(struct bt_component *comp) +uint64_t bt_component_get_output_port_count(struct bt_component *comp) { - BT_ASSERT(comp); - return (int64_t) comp->output_ports->len; + BT_ASSERT_PRE_NON_NULL(comp, "Component"); + return (uint64_t) comp->output_ports->len; } BT_HIDDEN -enum bt_component_status bt_component_create( - struct bt_component_class *component_class, +int bt_component_create(struct bt_component_class *component_class, const char *name, struct bt_component **user_component) { - enum bt_component_status status = BT_COMPONENT_STATUS_OK; + int ret = 0; struct bt_component *component = NULL; enum bt_component_class_type type; @@ -252,24 +267,23 @@ enum bt_component_status bt_component_create( BT_ASSERT(name); type = bt_component_class_get_type(component_class); - 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); + BT_LIB_LOGD("Creating empty component from component class: %![cc-]+C, " + "comp-name=\"%s\"", component_class, name); component = component_create_funcs[type](component_class); if (!component) { BT_LOGE_STR("Cannot create specific component object."); - status = BT_COMPONENT_STATUS_NOMEM; + ret = -1; goto end; } bt_object_init_shared_with_parent(&component->base, - bt_component_destroy); + destroy_component); component->class = bt_object_get_ref(component_class); component->destroy = component_destroy_funcs[type]; component->name = g_string_new(name); if (!component->name) { BT_LOGE_STR("Failed to allocate one GString."); - status = BT_COMPONENT_STATUS_NOMEM; + ret = -1; goto end; } @@ -277,7 +291,7 @@ enum bt_component_status bt_component_create( (GDestroyNotify) bt_object_try_spec_release); if (!component->input_ports) { BT_LOGE_STR("Failed to allocate one GPtrArray."); - status = BT_COMPONENT_STATUS_NOMEM; + ret = -1; goto end; } @@ -285,7 +299,7 @@ enum bt_component_status bt_component_create( (GDestroyNotify) bt_object_try_spec_release); if (!component->output_ports) { BT_LOGE_STR("Failed to allocate one GPtrArray."); - status = BT_COMPONENT_STATUS_NOMEM; + ret = -1; goto end; } @@ -293,72 +307,48 @@ enum bt_component_status bt_component_create( sizeof(struct bt_component_destroy_listener)); if (!component->destroy_listeners) { BT_LOGE_STR("Failed to allocate one GArray."); - status = BT_COMPONENT_STATUS_NOMEM; + ret = -1; goto end; } - 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_LIB_LOGD("Created empty component from component class: " + "%![cc-]+C, %![comp-]+c", component_class, component); BT_OBJECT_MOVE_REF(*user_component, component); end: bt_object_put_ref(component); - return status; + return ret; } const char *bt_component_get_name(struct bt_component *component) { - const char *ret = NULL; - - if (!component) { - BT_LOGW_STR("Invalid parameter: component is NULL."); - goto end; - } - - ret = component->name->len == 0 ? NULL : component->name->str; - -end: - return ret; + BT_ASSERT_PRE_NON_NULL(component, "Component"); + return component->name->str; } -struct bt_component_class *bt_component_get_class( +struct bt_component_class *bt_component_borrow_class( struct bt_component *component) { - return component ? bt_object_get_ref(component->class) : NULL; + BT_ASSERT_PRE_NON_NULL(component, "Component"); + return component->class; } -void *bt_private_component_get_user_data( - struct bt_private_component *private_component) +void *bt_self_component_get_data(struct bt_self_component *self_comp) { - struct bt_component *component = - bt_component_borrow_from_private(private_component); + struct bt_component *component = (void *) self_comp; - return component ? component->user_data : NULL; + BT_ASSERT_PRE_NON_NULL(component, "Component"); + return component->user_data; } -enum bt_component_status bt_private_component_set_user_data( - struct bt_private_component *private_component, +void bt_self_component_set_data(struct bt_self_component *self_comp, void *data) { - struct bt_component *component = - bt_component_borrow_from_private(private_component); - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - - if (!component) { - BT_LOGW_STR("Invalid parameter: component is NULL."); - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } + struct bt_component *component = (void *) self_comp; + BT_ASSERT_PRE_NON_NULL(component, "Component"); component->user_data = data; - BT_LOGV("Set component's user data: " - "comp-addr=%p, comp-name=\"%s\", user-data-addr=%p", - component, bt_component_get_name(component), data); - -end: - return ret; + BT_LIB_LOGV("Set component's user data: %!+c", component); } BT_HIDDEN @@ -376,24 +366,19 @@ bt_bool bt_component_graph_is_canceled(struct bt_component *component) } static -struct bt_port *bt_component_get_port_by_name(GPtrArray *ports, +struct bt_port *borrow_port_by_name(GPtrArray *ports, const char *name) { - size_t i; + uint64_t i; struct bt_port *ret_port = NULL; BT_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); - if (!port_name) { - continue; - } - - if (!strcmp(name, port_name)) { - ret_port = bt_object_get_ref(port); + if (!strcmp(name, port->name->str)) { + ret_port = port; break; } } @@ -402,81 +387,74 @@ struct bt_port *bt_component_get_port_by_name(GPtrArray *ports, } BT_HIDDEN -struct bt_port *bt_component_get_input_port_by_name(struct bt_component *comp, - const char *name) +struct bt_port_input *bt_component_borrow_input_port_by_name( + struct bt_component *comp, const char *name) { BT_ASSERT(comp); - - return bt_component_get_port_by_name(comp->input_ports, name); + return (void *) borrow_port_by_name(comp->input_ports, name); } BT_HIDDEN -struct bt_port *bt_component_get_output_port_by_name(struct bt_component *comp, - const char *name) +struct bt_port_output *bt_component_borrow_output_port_by_name( + struct bt_component *comp, const char *name) { - BT_ASSERT(comp); - - return bt_component_get_port_by_name(comp->output_ports, name); + BT_ASSERT_PRE_NON_NULL(comp, "Component"); + return (void *) + borrow_port_by_name(comp->output_ports, name); } static -struct bt_port *bt_component_get_port_by_index(GPtrArray *ports, uint64_t index) +struct bt_port *borrow_port_by_index(GPtrArray *ports, uint64_t index) { - struct bt_port *port = NULL; - - if (index >= ports->len) { - BT_LOGW("Invalid parameter: index is out of bounds: " - "index=%" PRIu64 ", count=%u", - index, ports->len); - goto end; - } - - port = bt_object_get_ref(g_ptr_array_index(ports, index)); -end: - return port; + BT_ASSERT(index < ports->len); + return g_ptr_array_index(ports, index); } BT_HIDDEN -struct bt_port *bt_component_get_input_port_by_index(struct bt_component *comp, - uint64_t index) +struct bt_port_input *bt_component_borrow_input_port_by_index( + struct bt_component *comp, uint64_t index) { - BT_ASSERT(comp); - - return bt_component_get_port_by_index(comp->input_ports, index); + BT_ASSERT_PRE_NON_NULL(comp, "Component"); + BT_ASSERT_PRE_VALID_INDEX(index, comp->input_ports->len); + return (void *) + borrow_port_by_index(comp->input_ports, index); } BT_HIDDEN -struct bt_port *bt_component_get_output_port_by_index(struct bt_component *comp, - uint64_t index) +struct bt_port_output *bt_component_borrow_output_port_by_index( + struct bt_component *comp, uint64_t index) { - BT_ASSERT(comp); - - return bt_component_get_port_by_index(comp->output_ports, index); + BT_ASSERT_PRE_NON_NULL(comp, "Component"); + BT_ASSERT_PRE_VALID_INDEX(index, comp->output_ports->len); + return (void *) + borrow_port_by_index(comp->output_ports, index); } BT_HIDDEN -struct bt_port *bt_component_add_input_port( +struct bt_port_input *bt_component_add_input_port( struct bt_component *component, const char *name, void *user_data) { - /* bt_component_add_port() logs details */ - return bt_component_add_port(component, component->input_ports, - BT_PORT_TYPE_INPUT, name, user_data); + /* add_port() logs details */ + return (void *) + add_port(component, component->input_ports, + BT_PORT_TYPE_INPUT, name, user_data); } BT_HIDDEN -struct bt_port *bt_component_add_output_port( +struct bt_port_output *bt_component_add_output_port( struct bt_component *component, const char *name, void *user_data) { - /* bt_component_add_port() logs details */ - return bt_component_add_port(component, component->output_ports, - BT_PORT_TYPE_OUTPUT, name, user_data); + /* add_port() logs details */ + return (void *) + add_port(component, component->output_ports, + BT_PORT_TYPE_OUTPUT, name, user_data); } static -void bt_component_remove_port_by_index(struct bt_component *component, - GPtrArray *ports, size_t index) +void remove_port_by_index(struct bt_component *component, + GPtrArray *ports, uint64_t index) { struct bt_port *port; struct bt_graph *graph; @@ -484,64 +462,80 @@ void bt_component_remove_port_by_index(struct bt_component *component, BT_ASSERT(ports); BT_ASSERT(index < ports->len); port = g_ptr_array_index(ports, index); - - BT_LOGD("Removing port from component: " - "comp-addr=%p, comp-name=\"%s\", " - "port-addr=%p, port-name=\"%s\"", - component, bt_component_get_name(component), - port, bt_port_get_name(port)); + BT_LIB_LOGD("Removing port from component: %![comp-]+c, %![port-]+p", + component, port); /* Disconnect both ports of this port's connection, if any */ if (port->connection) { bt_connection_end(port->connection, true); } - /* Remove from parent's array of ports (weak refs) */ + /* + * The port's current reference count can be 0 at this point, + * which means its parent (component) keeps it alive. We are + * about to remove the port from its parent's container (with + * the g_ptr_array_remove_index() call below), which in this + * case would destroy it. This is not good because we still + * need the port for the bt_graph_notify_port_removed() call + * below (in which its component is `NULL` as expected because + * of the bt_object_set_parent() call below). + * + * To avoid a destroyed port during the notification callback, + * get a reference now, and put it (destroying the port if its + * reference count is 0 at this point) after notifying the + * private graph's user. + */ + bt_object_get_no_null_check(&port->base); + + /* + * Remove from parent's array of ports (weak refs). This never + * destroys the port object because its reference count is at + * least 1 thanks to the bt_object_get_no_null_check() call + * above. + */ g_ptr_array_remove_index(ports, index); /* Detach port from its component parent */ - BT_OBJECT_PUT_REF_AND_RESET(port->base.parent); + bt_object_set_parent(&port->base, NULL); /* * Notify the graph's creator that a port is removed. */ - graph = bt_object_get_ref(bt_component_borrow_graph(component)); + graph = bt_component_borrow_graph(component); if (graph) { bt_graph_notify_port_removed(graph, component, port); - BT_OBJECT_PUT_REF_AND_RESET(graph); } - BT_LOGD("Removed port from component: " - "comp-addr=%p, comp-name=\"%s\", " - "port-addr=%p, port-name=\"%s\"", - component, bt_component_get_name(component), - port, bt_port_get_name(port)); + BT_LIB_LOGD("Removed port from component: %![comp-]+c, %![port-]+p", + component, port); + + /* + * Put the local reference. If this port's reference count was 0 + * when entering this function, it is 1 now, so it is destroyed + * immediately. + */ + bt_object_put_no_null_check(&port->base); } BT_HIDDEN -enum bt_component_status bt_component_remove_port( - struct bt_component *component, struct bt_port *port) +void bt_component_remove_port(struct bt_component *component, + struct bt_port *port) { - size_t i; - enum bt_component_status status = BT_COMPONENT_STATUS_OK; + uint64_t i; GPtrArray *ports = NULL; - if (!component) { - BT_LOGW_STR("Invalid parameter: component is NULL."); - status = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - if (!port) { - BT_LOGW_STR("Invalid parameter: port is NULL."); - status = BT_COMPONENT_STATUS_INVALID; - goto end; - } + BT_ASSERT(component); + BT_ASSERT(port); - if (bt_port_get_type(port) == BT_PORT_TYPE_INPUT) { + switch (port->type) { + case BT_PORT_TYPE_INPUT: ports = component->input_ports; - } else if (bt_port_get_type(port) == BT_PORT_TYPE_OUTPUT) { + break; + case BT_PORT_TYPE_OUTPUT: ports = component->output_ports; + break; + default: + abort(); } BT_ASSERT(ports); @@ -550,74 +544,168 @@ enum bt_component_status bt_component_remove_port( struct bt_port *cur_port = g_ptr_array_index(ports, i); if (cur_port == port) { - bt_component_remove_port_by_index(component, + remove_port_by_index(component, ports, i); goto end; } } - status = BT_COMPONENT_STATUS_NOT_FOUND; - BT_LOGW("Port to remove from component was not found: " - "comp-addr=%p, comp-name=\"%s\", " - "port-addr=%p, port-name=\"%s\"", - component, bt_component_get_name(component), - port, bt_port_get_name(port)); + BT_LIB_LOGW("Port to remove from component was not found: " + "%![comp-]+c, %![port-]+p", component, port); end: - return status; + return; } BT_HIDDEN -enum bt_component_status bt_component_accept_port_connection( +enum bt_self_component_status bt_component_accept_port_connection( struct bt_component *comp, struct bt_port *self_port, struct bt_port *other_port) { - enum bt_component_status status = BT_COMPONENT_STATUS_OK; + typedef enum bt_self_component_status (*method_t)( + void *, void *, void *); + + enum bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; + method_t method = NULL; BT_ASSERT(comp); BT_ASSERT(self_port); BT_ASSERT(other_port); - if (comp->class->methods.accept_port_connection) { - BT_LOGD("Calling user's \"accept port connection\" method: " - "comp-addr=%p, comp-name=\"%s\", " - "self-port-addr=%p, self-port-name=\"%s\", " - "other-port-addr=%p, other-port-name=\"%s\"", - comp, bt_component_get_name(comp), - self_port, bt_port_get_name(self_port), - other_port, bt_port_get_name(other_port)); - status = comp->class->methods.accept_port_connection( - bt_private_component_from_component(comp), - bt_private_port_from_port(self_port), - other_port); + switch (comp->class->type) { + case BT_COMPONENT_CLASS_TYPE_SOURCE: + { + struct bt_component_class_source *src_cc = (void *) comp->class; + + switch (self_port->type) { + case BT_PORT_TYPE_OUTPUT: + method = (method_t) src_cc->methods.accept_output_port_connection; + break; + default: + abort(); + } + + break; + } + case BT_COMPONENT_CLASS_TYPE_FILTER: + { + struct bt_component_class_filter *flt_cc = (void *) comp->class; + + switch (self_port->type) { + case BT_PORT_TYPE_INPUT: + method = (method_t) flt_cc->methods.accept_input_port_connection; + break; + case BT_PORT_TYPE_OUTPUT: + method = (method_t) flt_cc->methods.accept_output_port_connection; + break; + default: + abort(); + } + + break; + } + case BT_COMPONENT_CLASS_TYPE_SINK: + { + struct bt_component_class_sink *sink_cc = (void *) comp->class; + + switch (self_port->type) { + case BT_PORT_TYPE_INPUT: + method = (method_t) sink_cc->methods.accept_input_port_connection; + break; + default: + abort(); + } + + break; + } + default: + abort(); + } + + if (method) { + BT_LIB_LOGD("Calling user's \"accept port connection\" method: " + "%![comp-]+c, %![self-port-]+p, %![other-port-]+p", + comp, self_port, other_port); + status = method(comp, self_port, other_port); BT_LOGD("User method returned: status=%s", - bt_component_status_string(status)); + bt_self_component_status_string(status)); } return status; } BT_HIDDEN -enum bt_component_status bt_component_port_connected(struct bt_component *comp, - struct bt_port *self_port, struct bt_port *other_port) +enum bt_self_component_status bt_component_port_connected( + struct bt_component *comp, struct bt_port *self_port, + struct bt_port *other_port) { - enum bt_component_status status = BT_COMPONENT_STATUS_OK; + typedef enum bt_self_component_status (*method_t)( + void *, void *, void *); + + enum bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; + method_t method = NULL; BT_ASSERT(comp); BT_ASSERT(self_port); BT_ASSERT(other_port); - if (comp->class->methods.port_connected) { - BT_LOGD("Calling user's \"port connected\" method: " - "comp-addr=%p, comp-name=\"%s\", " - "self-port-addr=%p, self-port-name=\"%s\", " - "other-port-addr=%p, other-port-name=\"%s\"", - comp, bt_component_get_name(comp), - self_port, bt_port_get_name(self_port), - other_port, bt_port_get_name(other_port)); - status = comp->class->methods.port_connected( - bt_private_component_from_component(comp), - bt_private_port_from_port(self_port), other_port); + switch (comp->class->type) { + case BT_COMPONENT_CLASS_TYPE_SOURCE: + { + struct bt_component_class_source *src_cc = (void *) comp->class; + + switch (self_port->type) { + case BT_PORT_TYPE_OUTPUT: + method = (method_t) src_cc->methods.output_port_connected; + break; + default: + abort(); + } + + break; + } + case BT_COMPONENT_CLASS_TYPE_FILTER: + { + struct bt_component_class_filter *flt_cc = (void *) comp->class; + + switch (self_port->type) { + case BT_PORT_TYPE_INPUT: + method = (method_t) flt_cc->methods.input_port_connected; + break; + case BT_PORT_TYPE_OUTPUT: + method = (method_t) flt_cc->methods.output_port_connected; + break; + default: + abort(); + } + + break; + } + case BT_COMPONENT_CLASS_TYPE_SINK: + { + struct bt_component_class_sink *sink_cc = (void *) comp->class; + + switch (self_port->type) { + case BT_PORT_TYPE_INPUT: + method = (method_t) sink_cc->methods.input_port_connected; + break; + default: + abort(); + } + + break; + } + default: + abort(); + } + + if (method) { + BT_LIB_LOGD("Calling user's \"port connected\" method: " + "%![comp-]+c, %![self-port-]+p, %![other-port-]+p", + comp, self_port, other_port); + status = method(comp, self_port, other_port); + BT_LOGD("User method returned: status=%s", + bt_self_component_status_string(status)); } return status; @@ -627,18 +715,67 @@ BT_HIDDEN void bt_component_port_disconnected(struct bt_component *comp, struct bt_port *port) { + typedef void (*method_t)(void *, void *); + + method_t method = NULL; + BT_ASSERT(comp); BT_ASSERT(port); - if (comp->class->methods.port_disconnected) { - BT_LOGD("Calling user's \"port disconnected\" method: " - "comp-addr=%p, comp-name=\"%s\", " - "port-addr=%p, port-name=\"%s\"", - comp, bt_component_get_name(comp), - port, bt_port_get_name(port)); - comp->class->methods.port_disconnected( - bt_private_component_from_component(comp), - bt_private_port_from_port(port)); + switch (comp->class->type) { + case BT_COMPONENT_CLASS_TYPE_SOURCE: + { + struct bt_component_class_source *src_cc = (void *) comp->class; + + switch (port->type) { + case BT_PORT_TYPE_OUTPUT: + method = (method_t) src_cc->methods.output_port_disconnected; + break; + default: + abort(); + } + + break; + } + case BT_COMPONENT_CLASS_TYPE_FILTER: + { + struct bt_component_class_filter *flt_cc = (void *) comp->class; + + switch (port->type) { + case BT_PORT_TYPE_INPUT: + method = (method_t) flt_cc->methods.input_port_disconnected; + break; + case BT_PORT_TYPE_OUTPUT: + method = (method_t) flt_cc->methods.output_port_disconnected; + break; + default: + abort(); + } + + break; + } + case BT_COMPONENT_CLASS_TYPE_SINK: + { + struct bt_component_class_sink *sink_cc = (void *) comp->class; + + switch (port->type) { + case BT_PORT_TYPE_INPUT: + method = (method_t) sink_cc->methods.input_port_disconnected; + break; + default: + abort(); + } + + break; + } + default: + abort(); + } + + if (method) { + BT_LIB_LOGD("Calling user's \"port disconnected\" method: " + "%![comp-]+c, %![port-]+p", comp, port); + method(comp, port); } } @@ -653,18 +790,16 @@ void bt_component_add_destroy_listener(struct bt_component *component, listener.func = func; listener.data = data; g_array_append_val(component->destroy_listeners, listener); - BT_LOGV("Added destroy listener: " - "comp-addr=%p, comp-name=\"%s\", " + BT_LIB_LOGV("Added destroy listener: %![comp-]+c, " "func-addr=%p, data-addr=%p", - component, bt_component_get_name(component), - func, data); + component, func, data); } BT_HIDDEN void bt_component_remove_destroy_listener(struct bt_component *component, bt_component_destroy_listener_func func, void *data) { - size_t i; + uint64_t i; BT_ASSERT(component); BT_ASSERT(func); @@ -677,11 +812,9 @@ void bt_component_remove_destroy_listener(struct bt_component *component, if (listener->func == func && listener->data == data) { g_array_remove_index(component->destroy_listeners, i); i--; - BT_LOGV("Removed destroy listener: " - "comp-addr=%p, comp-name=\"%s\", " + BT_LIB_LOGV("Removed destroy listener: %![comp-]+c, " "func-addr=%p, data-addr=%p", - component, bt_component_get_name(component), - func, data); + component, func, data); } } }