示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}