int bt_ctf_stream_append_event(struct bt_ctf_stream *stream, struct bt_ctf_event *event) { int ret = 0; if (!stream || !event || stream->pos.fd < 0) { ret = -1; goto end; } /* * The event is not supposed to have a parent stream at this * point. The only other way an event can have a parent stream * is if it was assigned when setting a packet to the event, * in which case the packet's stream is not a writer stream, * and thus the user is trying to append an event which belongs * to another stream. */ if (event->base.parent) { ret = -1; goto end; } bt_object_set_parent(event, stream); ret = bt_ctf_event_populate_event_header(event); if (ret) { goto error; } /* Make sure the various scopes of the event are set */ ret = bt_ctf_event_validate(event); if (ret) { goto error; } /* Save the new event and freeze it */ bt_ctf_event_freeze(event); g_ptr_array_add(stream->events, event); /* * Event had to hold a reference to its event class as long as it wasn't * part of the same trace hierarchy. From now on, the event and its * class share the same lifetime guarantees and the reference is no * longer needed. */ bt_put(event->event_class); end: return ret; error: /* * Orphan the event; we were not successful in associating it to * a stream. */ bt_object_set_parent(event, NULL); return ret; }
BT_HIDDEN struct bt_port *bt_port_create(struct bt_component *parent_component, enum bt_port_type type, const char *name, void *user_data) { struct bt_port *port = NULL; assert(name); assert(parent_component); assert(type == BT_PORT_TYPE_INPUT || type == BT_PORT_TYPE_OUTPUT); if (strlen(name) == 0) { BT_LOGW_STR("Invalid parameter: name is an empty string."); goto end; } port = g_new0(struct bt_port, 1); if (!port) { BT_LOGE_STR("Failed to allocate one port."); goto end; } BT_LOGD("Creating port for component: " "comp-addr=%p, comp-name=\"%s\", port-type=%s, " "port-name=\"%s\"", parent_component, bt_component_get_name(parent_component), bt_port_type_string(type), name); bt_object_init(port, bt_port_destroy); port->name = g_string_new(name); if (!port->name) { BT_LOGE_STR("Failed to allocate one GString."); BT_PUT(port); goto end; } port->type = type; port->user_data = user_data; bt_object_set_parent(port, &parent_component->base); BT_LOGD("Created port for component: " "comp-addr=%p, comp-name=\"%s\", port-type=%s, " "port-name=\"%s\", port-addr=%p", parent_component, bt_component_get_name(parent_component), bt_port_type_string(type), name, port); end: return port; }
struct bt_ctf_stream *bt_ctf_stream_create( struct bt_ctf_stream_class *stream_class, const char *name) { int ret; struct bt_ctf_stream *stream = NULL; struct bt_ctf_trace *trace = NULL; struct bt_ctf_writer *writer = NULL; if (!stream_class) { goto error; } trace = bt_ctf_stream_class_get_trace(stream_class); if (!trace) { goto error; } stream = g_new0(struct bt_ctf_stream, 1); if (!stream) { goto error; } bt_object_init(stream, bt_ctf_stream_destroy); /* * Acquire reference to parent since stream will become publicly * reachable; it needs its parent to remain valid. */ bt_object_set_parent(stream, trace); stream->id = stream_class->next_stream_id++; stream->stream_class = stream_class; stream->pos.fd = -1; if (name) { stream->name = g_string_new(name); if (!stream->name) { goto error; } } if (trace->is_created_by_writer) { int fd; writer = (struct bt_ctf_writer *) bt_object_get_parent(trace); assert(writer); stream->packet_context = bt_ctf_field_create( stream_class->packet_context_type); if (!stream->packet_context) { goto error; } /* Initialize events_discarded */ ret = set_structure_field_integer(stream->packet_context, "events_discarded", 0); if (ret) { goto error; } stream->events = g_ptr_array_new_with_free_func( (GDestroyNotify) release_event); if (!stream->events) { goto error; } /* A trace is not allowed to have a NULL packet header */ assert(trace->packet_header_type); stream->packet_header = bt_ctf_field_create(trace->packet_header_type); if (!stream->packet_header) { goto error; } /* * Attempt to populate the default trace packet header fields * (magic, uuid and stream_id). This will _not_ fail shall the * fields not be found or be of an incompatible type; they will * simply not be populated automatically. The user will have to * make sure to set the trace packet header fields himself * before flushing. */ ret = set_packet_header(stream); if (ret) { goto error; } /* Create file associated with this stream */ fd = create_stream_file(writer, stream); if (fd < 0) { goto error; } ret = set_stream_fd(stream, fd); if (ret) { goto error; } /* Freeze the writer */ bt_ctf_writer_freeze(writer); } else { /* Non-writer stream indicated by a negative FD */ ret = set_stream_fd(stream, -1); if (ret) { goto error; } stream->clock_values = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); } /* Add this stream to the trace's streams */ g_ptr_array_add(trace->streams, stream); BT_PUT(trace); BT_PUT(writer); return stream; error: BT_PUT(stream); BT_PUT(trace); BT_PUT(writer); return stream; }