Exemple #1
0
struct bt_ctf_stream *bt_ctf_writer_create_stream(struct bt_ctf_writer *writer,
		struct bt_ctf_stream_class *stream_class)
{
	int ret;
	int stream_class_found = 0;
	size_t i;
	int stream_fd;
	struct bt_ctf_stream *stream = NULL;

	if (!writer || !stream_class) {
		goto error;
	}

	ret = bt_ctf_stream_class_set_byte_order(stream_class,
		writer->byte_order == LITTLE_ENDIAN ?
		BT_CTF_BYTE_ORDER_LITTLE_ENDIAN : BT_CTF_BYTE_ORDER_BIG_ENDIAN);
	if (ret) {
		goto error;
	}

	stream = bt_ctf_stream_create(stream_class);
	if (!stream) {
		goto error;
	}

	stream_fd = create_stream_file(writer, stream);
	if (stream_fd < 0 || bt_ctf_stream_set_fd(stream, stream_fd)) {
		goto error;
	}

	bt_ctf_stream_set_flush_callback(stream, (flush_func)stream_flush_cb,
		writer);

	for (i = 0; i < writer->stream_classes->len; i++) {
		if (writer->stream_classes->pdata[i] == stream->stream_class) {
			stream_class_found = 1;
		}
	}

	if (!stream_class_found) {
		int64_t stream_id = bt_ctf_stream_class_get_id(stream_class);
		if (stream_id < 0) {
			if (bt_ctf_stream_class_set_id(stream->stream_class,
				writer->next_stream_id++)) {
				goto error;
			}
		}

		for (i = 0; i < writer->stream_classes->len; i++) {
			if (stream_id == bt_ctf_stream_class_get_id(
				    writer->stream_classes->pdata[i])) {
				/* Duplicate stream id found */
				goto error;
			}
		}
		bt_ctf_stream_class_get(stream->stream_class);
		g_ptr_array_add(writer->stream_classes, stream->stream_class);
	}

	bt_ctf_stream_get(stream);
	g_ptr_array_add(writer->streams, stream);
	writer->frozen = 1;
	return stream;
error:
	bt_ctf_stream_put(stream);
	return NULL;
}
Exemple #2
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;
}