X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fgraph%2Fcomponent.c;h=6da601c89295975edc8a86228b35fed59408c4af;hb=e5be10efe4d5543ba697c7e607ca0a5c33fa3ccb;hp=9ed599448880b647d4d122fd9c50c2d8bb297cde;hpb=bd14d76835630e092320c8a04300088242dcdc99;p=babeltrace.git diff --git a/lib/graph/component.c b/lib/graph/component.c index 9ed59944..6da601c8 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -1,8 +1,4 @@ /* - * component.c - * - * Babeltrace Plugin Component - * * Copyright 2015 Jérémie Galarneau * * Author: Jérémie Galarneau @@ -26,6 +22,9 @@ * SOFTWARE. */ +#define BT_LOG_TAG "COMP" +#include + #include #include #include @@ -37,16 +36,20 @@ #include #include #include -#include +#include #include #include -#include +#include #include +#include +#include +#include #include +#include static struct bt_component * (* const component_create_funcs[])( - struct bt_component_class *, struct bt_value *) = { + struct bt_component_class *) = { [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_create, [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_create, [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create, @@ -59,14 +62,6 @@ void (*component_destroy_funcs[])(struct bt_component *) = { [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_destroy, }; -static -enum bt_component_status (* const component_validation_funcs[])( - struct bt_component *) = { - [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_validate, - [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_validate, - [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_validate, -}; - static void bt_component_destroy(struct bt_object *obj) { @@ -82,15 +77,20 @@ 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_get() (or anything that causes bt_get() to + * 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_put(): the reference count would go from 1 to 0 again and + * bt_object_put_ref(): the reference count would go from 1 to 0 again and * this function would be called again. */ - obj->ref_count.count++; + 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); /* Call destroy listeners in reverse registration order */ + BT_LOGD_STR("Calling destroy listeners."); + for (i = component->destroy_listeners->len - 1; i >= 0; i--) { struct bt_component_destroy_listener *listener = &g_array_index(component->destroy_listeners, @@ -102,23 +102,28 @@ void bt_component_destroy(struct bt_object *obj) component_class = component->class; /* - * User data is destroyed first, followed by the concrete component - * instance. + * User data is destroyed first, followed by the concrete + * component instance. Do not finalize if the component's user + * initialization method failed in the first place. */ - if (component->class->methods.finalize) { + if (component->initialized && component->class->methods.finalize) { + BT_LOGD_STR("Calling user's finalization method."); component->class->methods.finalize( bt_private_component_from_component(component)); } if (component->destroy) { + BT_LOGD_STR("Destroying type-specific data."); component->destroy(component); } if (component->input_ports) { + BT_LOGD_STR("Destroying input ports."); g_ptr_array_free(component->input_ports, TRUE); } if (component->output_ports) { + BT_LOGD_STR("Destroying output ports."); g_ptr_array_free(component->output_ports, TRUE); } @@ -126,15 +131,19 @@ void bt_component_destroy(struct bt_object *obj) g_array_free(component->destroy_listeners, TRUE); } - g_string_free(component->name, TRUE); - bt_put(component_class); + if (component->name) { + g_string_free(component->name, TRUE); + } + + BT_LOGD("Putting component class."); + bt_object_put_ref(component_class); g_free(component); } -struct bt_component *bt_component_from_private_component( +struct bt_component *bt_component_borrow_from_private( struct bt_private_component *private_component) { - return bt_get(bt_component_from_private(private_component)); + return (void *) private_component; } enum bt_component_class_type bt_component_get_class_type( @@ -152,29 +161,40 @@ struct bt_port *bt_component_add_port( struct bt_port *new_port = NULL; struct bt_graph *graph = NULL; - if (!name || strlen(name) == 0) { + if (!name) { + BT_LOGW_STR("Invalid parameter: name is NULL."); goto end; } + if (strlen(name) == 0) { + BT_LOGW_STR("Invalid parameter: name is an empty string."); + goto end; + } + + BT_LOGD("Adding port to component: comp-addr=%p, comp-name=\"%s\", " + "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); + struct bt_port *port = g_ptr_array_index(ports, i); port_name = bt_port_get_name(port); - if (!port_name) { - continue; - } + 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."); goto end; } @@ -189,12 +209,17 @@ struct bt_port *bt_component_add_port( /* * Notify the graph's creator that a new port was added. */ - graph = bt_component_get_graph(component); + graph = bt_object_get_ref(bt_component_borrow_graph(component)); if (graph) { bt_graph_notify_port_added(graph, new_port); - BT_PUT(graph); + 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); + end: return new_port; } @@ -202,119 +227,85 @@ end: BT_HIDDEN int64_t bt_component_get_input_port_count(struct bt_component *comp) { - assert(comp); + BT_ASSERT(comp); return (int64_t) comp->input_ports->len; } BT_HIDDEN int64_t bt_component_get_output_port_count(struct bt_component *comp) { - assert(comp); + BT_ASSERT(comp); return (int64_t) comp->output_ports->len; } -struct bt_component *bt_component_create_with_init_method_data( - struct bt_component_class *component_class, const char *name, - struct bt_value *params, void *init_method_data) +BT_HIDDEN +enum bt_component_status bt_component_create( + struct bt_component_class *component_class, + const char *name, struct bt_component **user_component) { - int ret; + enum bt_component_status status = BT_COMPONENT_STATUS_OK; struct bt_component *component = NULL; enum bt_component_class_type type; - bt_get(params); - - if (!component_class) { - goto end; - } + BT_ASSERT(user_component); + BT_ASSERT(component_class); + BT_ASSERT(name); type = bt_component_class_get_type(component_class); - if (type <= BT_COMPONENT_CLASS_TYPE_UNKNOWN || - type > BT_COMPONENT_CLASS_TYPE_FILTER) { - goto end; - } - - /* - * Parameters must be a map value, but we create a convenient - * empty one if it's NULL. - */ - if (params) { - if (!bt_value_is_map(params)) { - goto end; - } - } else { - params = bt_value_map_create(); - if (!params) { - goto end; - } - } - - component = component_create_funcs[type](component_class, params); + BT_LOGD("Creating empty component from component class: " + "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\"", + component_class, bt_component_class_type_string(type), name); + component = component_create_funcs[type](component_class); if (!component) { + BT_LOGE_STR("Cannot create specific component object."); + status = BT_COMPONENT_STATUS_NOMEM; goto end; } - bt_object_init(component, bt_component_destroy); - component->class = bt_get(component_class); + bt_object_init_shared_with_parent(&component->base, + bt_component_destroy); + component->class = bt_object_get_ref(component_class); component->destroy = component_destroy_funcs[type]; component->name = g_string_new(name); if (!component->name) { - BT_PUT(component); + BT_LOGE_STR("Failed to allocate one GString."); + status = BT_COMPONENT_STATUS_NOMEM; goto end; } component->input_ports = g_ptr_array_new_with_free_func( - bt_object_release); + (GDestroyNotify) bt_object_try_spec_release); if (!component->input_ports) { - BT_PUT(component); + BT_LOGE_STR("Failed to allocate one GPtrArray."); + status = BT_COMPONENT_STATUS_NOMEM; goto end; } component->output_ports = g_ptr_array_new_with_free_func( - bt_object_release); + (GDestroyNotify) bt_object_try_spec_release); if (!component->output_ports) { - BT_PUT(component); + BT_LOGE_STR("Failed to allocate one GPtrArray."); + status = BT_COMPONENT_STATUS_NOMEM; goto end; } component->destroy_listeners = g_array_new(FALSE, TRUE, sizeof(struct bt_component_destroy_listener)); if (!component->destroy_listeners) { - BT_PUT(component); + BT_LOGE_STR("Failed to allocate one GArray."); + status = BT_COMPONENT_STATUS_NOMEM; goto end; } - component->initializing = BT_TRUE; - - if (component_class->methods.init) { - ret = component_class->methods.init( - bt_private_component_from_component(component), params, - init_method_data); - component->initializing = BT_FALSE; - if (ret != BT_COMPONENT_STATUS_OK) { - BT_PUT(component); - goto end; - } - } - - component->initializing = BT_FALSE; - ret = component_validation_funcs[type](component); - if (ret != BT_COMPONENT_STATUS_OK) { - BT_PUT(component); - 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_OBJECT_MOVE_REF(*user_component, component); - bt_component_class_freeze(component->class); end: - bt_put(params); - return component; -} - -struct bt_component *bt_component_create( - struct bt_component_class *component_class, const char *name, - struct bt_value *params) -{ - return bt_component_create_with_init_method_data(component_class, name, - params, NULL); + bt_object_put_ref(component); + return status; } const char *bt_component_get_name(struct bt_component *component) @@ -322,25 +313,12 @@ 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; -} -enum bt_component_status bt_component_set_name(struct bt_component *component, - const char *name) -{ - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - - if (!component || !name || name[0] == '\0') { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - g_string_assign(component->name, name); end: return ret; } @@ -348,14 +326,14 @@ end: struct bt_component_class *bt_component_get_class( struct bt_component *component) { - return component ? bt_get(component->class) : NULL; + return component ? bt_object_get_ref(component->class) : NULL; } void *bt_private_component_get_user_data( struct bt_private_component *private_component) { struct bt_component *component = - bt_component_from_private(private_component); + bt_component_borrow_from_private(private_component); return component ? component->user_data : NULL; } @@ -365,15 +343,20 @@ enum bt_component_status bt_private_component_set_user_data( void *data) { struct bt_component *component = - bt_component_from_private(private_component); + bt_component_borrow_from_private(private_component); enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - if (!component || !component->initializing) { + if (!component) { + BT_LOGW_STR("Invalid parameter: component is NULL."); ret = BT_COMPONENT_STATUS_INVALID; goto end; } 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; } @@ -382,19 +365,14 @@ BT_HIDDEN void bt_component_set_graph(struct bt_component *component, struct bt_graph *graph) { - struct bt_object *parent = bt_object_get_parent(&component->base); - - assert(!parent || parent == &graph->base); - if (!parent) { - bt_object_set_parent(component, &graph->base); - } - bt_put(parent); + bt_object_set_parent(&component->base, + graph ? &graph->base : NULL); } -struct bt_graph *bt_component_get_graph( - struct bt_component *component) +bt_bool bt_component_graph_is_canceled(struct bt_component *component) { - return (struct bt_graph *) bt_object_get_parent(&component->base); + return bt_graph_is_canceled( + (void *) bt_object_borrow_parent(&component->base)); } static @@ -404,7 +382,7 @@ struct bt_port *bt_component_get_port_by_name(GPtrArray *ports, size_t i; struct bt_port *ret_port = NULL; - assert(name); + BT_ASSERT(name); for (i = 0; i < ports->len; i++) { struct bt_port *port = g_ptr_array_index(ports, i); @@ -415,7 +393,7 @@ struct bt_port *bt_component_get_port_by_name(GPtrArray *ports, } if (!strcmp(name, port_name)) { - ret_port = bt_get(port); + ret_port = bt_object_get_ref(port); break; } } @@ -427,7 +405,7 @@ BT_HIDDEN struct bt_port *bt_component_get_input_port_by_name(struct bt_component *comp, const char *name) { - assert(comp); + BT_ASSERT(comp); return bt_component_get_port_by_name(comp->input_ports, name); } @@ -436,7 +414,7 @@ BT_HIDDEN struct bt_port *bt_component_get_output_port_by_name(struct bt_component *comp, const char *name) { - assert(comp); + BT_ASSERT(comp); return bt_component_get_port_by_name(comp->output_ports, name); } @@ -447,10 +425,13 @@ struct bt_port *bt_component_get_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_get(g_ptr_array_index(ports, index)); + port = bt_object_get_ref(g_ptr_array_index(ports, index)); end: return port; } @@ -459,7 +440,7 @@ BT_HIDDEN struct bt_port *bt_component_get_input_port_by_index(struct bt_component *comp, uint64_t index) { - assert(comp); + BT_ASSERT(comp); return bt_component_get_port_by_index(comp->input_ports, index); } @@ -468,7 +449,7 @@ BT_HIDDEN struct bt_port *bt_component_get_output_port_by_index(struct bt_component *comp, uint64_t index) { - assert(comp); + BT_ASSERT(comp); return bt_component_get_port_by_index(comp->output_ports, index); } @@ -478,6 +459,7 @@ struct bt_port *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); } @@ -487,6 +469,7 @@ struct bt_port *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); } @@ -498,29 +481,41 @@ void bt_component_remove_port_by_index(struct bt_component *component, struct bt_port *port; struct bt_graph *graph; - assert(ports); - assert(index < ports->len); + 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)); + /* Disconnect both ports of this port's connection, if any */ if (port->connection) { - bt_connection_disconnect_ports(port->connection); + bt_connection_end(port->connection, true); } /* 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); + BT_OBJECT_PUT_REF_AND_RESET(port->base.parent); /* * Notify the graph's creator that a port is removed. */ - graph = bt_component_get_graph(component); + graph = bt_object_get_ref(bt_component_borrow_graph(component)); if (graph) { bt_graph_notify_port_removed(graph, component, port); - BT_PUT(graph); + 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_HIDDEN @@ -531,7 +526,14 @@ enum bt_component_status bt_component_remove_port( enum bt_component_status status = BT_COMPONENT_STATUS_OK; GPtrArray *ports = NULL; - if (!component || !port) { + 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; } @@ -542,7 +544,7 @@ enum bt_component_status bt_component_remove_port( ports = component->output_ports; } - assert(ports); + BT_ASSERT(ports); for (i = 0; i < ports->len; i++) { struct bt_port *cur_port = g_ptr_array_index(ports, i); @@ -555,6 +557,12 @@ enum bt_component_status bt_component_remove_port( } 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)); + end: return status; } @@ -566,43 +574,68 @@ enum bt_component_status bt_component_accept_port_connection( { enum bt_component_status status = BT_COMPONENT_STATUS_OK; - assert(comp); - assert(self_port); - assert(other_port); + 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); + BT_LOGD("User method returned: status=%s", + bt_component_status_string(status)); } return status; } BT_HIDDEN -void bt_component_port_connected(struct bt_component *comp, +enum bt_component_status bt_component_port_connected(struct bt_component *comp, struct bt_port *self_port, struct bt_port *other_port) { - assert(comp); - assert(self_port); - assert(other_port); + enum bt_component_status status = BT_COMPONENT_STATUS_OK; + + BT_ASSERT(comp); + BT_ASSERT(self_port); + BT_ASSERT(other_port); if (comp->class->methods.port_connected) { - 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); } + + return status; } BT_HIDDEN void bt_component_port_disconnected(struct bt_component *comp, struct bt_port *port) { - assert(comp); - assert(port); + 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)); @@ -615,11 +648,16 @@ void bt_component_add_destroy_listener(struct bt_component *component, { struct bt_component_destroy_listener listener; - assert(component); - assert(func); + BT_ASSERT(component); + BT_ASSERT(func); 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\", " + "func-addr=%p, data-addr=%p", + component, bt_component_get_name(component), + func, data); } BT_HIDDEN @@ -628,8 +666,8 @@ void bt_component_remove_destroy_listener(struct bt_component *component, { size_t i; - assert(component); - assert(func); + BT_ASSERT(component); + BT_ASSERT(func); for (i = 0; i < component->destroy_listeners->len; i++) { struct bt_component_destroy_listener *listener = @@ -639,6 +677,11 @@ 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\", " + "func-addr=%p, data-addr=%p", + component, bt_component_get_name(component), + func, data); } } }