+ typedef enum bt_self_message_iterator_status (*init_method_t)(
+ void *, void *, void *);
+
+ init_method_t init_method = NULL;
+ struct bt_self_component_port_input_message_iterator *iterator =
+ NULL;
+ struct bt_port *port = (void *) self_port;
+ struct bt_port *upstream_port;
+ struct bt_component *comp;
+ struct bt_component *upstream_comp;
+ struct bt_component_class *upstream_comp_cls;
+
+ BT_ASSERT_PRE_NON_NULL(port, "Port");
+ comp = bt_port_borrow_component_inline(port);
+ BT_ASSERT_PRE(bt_port_is_connected(port),
+ "Port is not connected: %![port-]+p", port);
+ BT_ASSERT_PRE(comp, "Port is not part of a component: %![port-]+p",
+ port);
+ BT_ASSERT_PRE(!bt_component_graph_is_canceled(comp),
+ "Port's component's graph is canceled: "
+ "%![port-]+p, %![comp-]+c", port, comp);
+ BT_ASSERT(port->connection);
+ upstream_port = port->connection->upstream_port;
+ BT_ASSERT(upstream_port);
+ upstream_comp = bt_port_borrow_component_inline(upstream_port);
+ BT_ASSERT(upstream_comp);
+ BT_ASSERT_PRE(
+ bt_component_borrow_graph(upstream_comp)->config_state !=
+ BT_GRAPH_CONFIGURATION_STATE_CONFIGURING,
+ "Graph is not configured: %!+g",
+ bt_component_borrow_graph(upstream_comp));
+ upstream_comp_cls = upstream_comp->class;
+ BT_ASSERT(upstream_comp->class->type ==
+ BT_COMPONENT_CLASS_TYPE_SOURCE ||
+ upstream_comp->class->type ==
+ BT_COMPONENT_CLASS_TYPE_FILTER);
+ iterator = bt_self_component_port_input_message_iterator_create_initial(
+ upstream_comp, upstream_port);
+ if (!iterator) {
+ BT_LOGW_STR("Cannot create self component input port "
+ "message iterator.");
+ goto end;
+ }
+
+ switch (upstream_comp_cls->type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ {
+ struct bt_component_class_source *src_comp_cls =
+ (void *) upstream_comp_cls;
+
+ init_method =
+ (init_method_t) src_comp_cls->methods.msg_iter_init;
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ {
+ struct bt_component_class_filter *flt_comp_cls =
+ (void *) upstream_comp_cls;
+
+ init_method =
+ (init_method_t) flt_comp_cls->methods.msg_iter_init;
+ break;
+ }
+ default:
+ /* Unreachable */
+ abort();
+ }
+
+ if (init_method) {
+ int iter_status;
+
+ BT_LIB_LOGD("Calling user's initialization method: %!+i", iterator);
+ iter_status = init_method(iterator, upstream_comp,
+ upstream_port);
+ BT_LOGD("User method returned: status=%s",
+ bt_message_iterator_status_string(iter_status));
+ if (iter_status != BT_MESSAGE_ITERATOR_STATUS_OK) {
+ BT_LOGW_STR("Initialization method failed.");
+ BT_OBJECT_PUT_REF_AND_RESET(iterator);
+ goto end;
+ }
+ }
+
+ set_self_comp_port_input_msg_iterator_state(iterator,
+ BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ACTIVE);
+ g_ptr_array_add(port->connection->iterators, iterator);
+ BT_LIB_LOGD("Created message iterator on self component input port: "
+ "%![up-port-]+p, %![up-comp-]+c, %![iter-]+i",
+ upstream_port, upstream_comp, iterator);