+BT_HIDDEN
+void writer_close(struct writer_component *writer_component,
+ struct fs_writer *fs_writer)
+{
+ if (fs_writer->static_listener_id > 0) {
+ bt_ctf_trace_remove_is_static_listener(fs_writer->trace,
+ fs_writer->static_listener_id);
+ }
+
+ /* Empty the stream class HT. */
+ g_hash_table_foreach_remove(fs_writer->stream_class_map,
+ empty_ht, NULL);
+ g_hash_table_destroy(fs_writer->stream_class_map);
+
+ /* Empty the stream HT. */
+ g_hash_table_foreach_remove(fs_writer->stream_map,
+ empty_ht, NULL);
+ g_hash_table_destroy(fs_writer->stream_map);
+
+ /* Empty the stream state HT. */
+ g_hash_table_foreach_remove(fs_writer->stream_states,
+ empty_ht, NULL);
+ g_hash_table_destroy(fs_writer->stream_states);
+}
+
+BT_HIDDEN
+enum bt_component_status writer_stream_begin(
+ struct writer_component *writer_component,
+ struct bt_ctf_stream *stream)
+{
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct fs_writer *fs_writer;
+ struct bt_ctf_stream *writer_stream = NULL;
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ enum fs_writer_stream_state *state;
+
+ stream_class = bt_ctf_stream_get_class(stream);
+ if (!stream_class) {
+ fprintf(writer_component->err, "[error] %s in %s:%d\n",
+ __func__, __FILE__, __LINE__);
+ goto error;
+ }
+
+ fs_writer = get_fs_writer(writer_component, stream_class);
+ if (!fs_writer) {
+ fprintf(writer_component->err, "[error] %s in %s:%d\n",
+ __func__, __FILE__, __LINE__);
+ goto error;
+ }
+
+ /* Set the stream as active */
+ state = g_hash_table_lookup(fs_writer->stream_states, stream);
+ if (!state) {
+ if (fs_writer->trace_static) {
+ fprintf(writer_component->err, "[error] Adding a new "
+ "stream on a static trace\n");
+ goto error;
+ }
+ state = insert_new_stream_state(writer_component, fs_writer,
+ stream);
+ }
+ if (*state != FS_WRITER_UNKNOWN_STREAM) {
+ fprintf(writer_component->err, "[error] Unexpected stream "
+ "state %d\n", *state);
+ goto error;
+ }
+ *state = FS_WRITER_ACTIVE_STREAM;
+
+ writer_stream = insert_new_stream(writer_component, fs_writer,
+ stream_class, stream);
+ if (!writer_stream) {
+ fprintf(writer_component->err, "[error] %s in %s:%d\n",
+ __func__, __FILE__, __LINE__);
+ goto error;
+ }
+ fs_writer->active_streams++;
+
+ goto end;
+
+error:
+ ret = BT_COMPONENT_STATUS_ERROR;
+end:
+ bt_put(stream_class);
+ return ret;
+}
+
+void check_completed_trace(gpointer key, gpointer value, gpointer user_data)
+{
+ enum fs_writer_stream_state *state = value;
+ int *trace_completed = user_data;
+
+ if (*state != FS_WRITER_COMPLETED_STREAM) {
+ *trace_completed = 0;
+ }
+}
+
+BT_HIDDEN
+enum bt_component_status writer_stream_end(
+ struct writer_component *writer_component,
+ struct bt_ctf_stream *stream)
+{
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct fs_writer *fs_writer;
+ struct bt_ctf_trace *trace = NULL;
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ enum fs_writer_stream_state *state;
+
+ stream_class = bt_ctf_stream_get_class(stream);
+ if (!stream_class) {
+ fprintf(writer_component->err, "[error] %s in %s:%d\n",
+ __func__, __FILE__, __LINE__);
+ goto error;
+ }
+
+ fs_writer = get_fs_writer(writer_component, stream_class);
+ if (!fs_writer) {
+ fprintf(writer_component->err, "[error] %s in %s:%d\n",
+ __func__, __FILE__, __LINE__);
+ goto error;
+ }
+
+ state = g_hash_table_lookup(fs_writer->stream_states, stream);
+ if (*state != FS_WRITER_ACTIVE_STREAM) {
+ fprintf(writer_component->err, "[error] Unexpected stream "
+ "state %d\n", *state);
+ goto error;
+ }
+ *state = FS_WRITER_COMPLETED_STREAM;
+
+ g_hash_table_remove(fs_writer->stream_map, stream);
+
+ if (fs_writer->trace_static) {
+ int trace_completed = 1;
+
+ g_hash_table_foreach(fs_writer->stream_states,
+ check_completed_trace, &trace_completed);
+ if (trace_completed) {
+ writer_close(writer_component, fs_writer);
+ g_hash_table_remove(writer_component->trace_map,
+ fs_writer->trace);
+ }
+ }
+
+ goto end;
+
+error:
+ ret = BT_COMPONENT_STATUS_ERROR;
+end:
+ BT_PUT(trace);
+ BT_PUT(stream_class);
+ return ret;
+}
+