goto end;
}
+ /* Empty no monitor streams list. */
+ if (!channel->monitor) {
+ struct lttng_consumer_stream *stream, *stmp;
+
+ /*
+ * So, these streams are not visible to any data thread. This is why we
+ * close and free them because they were never added to any data
+ * structure apart from this one.
+ */
+ cds_list_for_each_entry_safe(stream, stmp,
+ &channel->stream_no_monitor_list.head, no_monitor_node) {
+ cds_list_del(&stream->no_monitor_node);
+ /* Close everything in that stream. */
+ consumer_stream_close(stream);
+ /* Free the ressource. */
+ consumer_stream_free(stream);
+ }
+ }
+
rcu_read_lock();
iter.iter.node = &channel->node.node;
ret = lttng_ht_del(consumer_data.channel_ht, &iter);
/* Init session id node with the stream session id */
lttng_ht_node_init_u64(&stream->node_session_id, stream->session_id);
- DBG3("Allocated stream %s (key %" PRIu64 ", chan_key %" PRIu64 " relayd_id %" PRIu64 ", session_id %" PRIu64,
- stream->name, stream->key, channel_key, stream->net_seq_idx, stream->session_id);
+ DBG3("Allocated stream %s (key %" PRIu64 ", chan_key %" PRIu64
+ " relayd_id %" PRIu64 ", session_id %" PRIu64,
+ stream->name, stream->key, channel_key,
+ stream->net_seq_idx, stream->session_id);
rcu_read_unlock();
return stream;
channel->tracefile_count = tracefile_count;
channel->monitor = monitor;
+ /*
+ * In monitor mode, the streams associated with the channel will be put in
+ * a special list ONLY owned by this channel. So, the refcount is set to 1
+ * here meaning that the channel itself has streams that are referenced.
+ *
+ * On a channel deletion, once the channel is no longer visible, the
+ * refcount is decremented and checked for a zero value to delete it. With
+ * streams in no monitor mode, it will now be safe to destroy the channel.
+ */
+ if (!channel->monitor) {
+ channel->refcount = 1;
+ }
+
+ switch (output) {
+ case LTTNG_EVENT_SPLICE:
+ channel->output = CONSUMER_CHANNEL_SPLICE;
+ break;
+ case LTTNG_EVENT_MMAP:
+ channel->output = CONSUMER_CHANNEL_MMAP;
+ break;
+ default:
+ ERR("Allocate channel output unknown %d", output);
+ free(channel);
+ channel = NULL;
+ goto end;
+ }
+
strncpy(channel->pathname, pathname, sizeof(channel->pathname));
channel->pathname[sizeof(channel->pathname) - 1] = '\0';
channel->wait_fd = -1;
CDS_INIT_LIST_HEAD(&channel->streams.head);
+ CDS_INIT_LIST_HEAD(&channel->stream_no_monitor_list.head);
DBG("Allocated channel (key %" PRIu64 ")", channel->key)
PERROR("munmap metadata stream");
}
}
-
if (stream->wait_fd >= 0) {
ret = close(stream->wait_fd);
if (ret < 0) {