Fix: consumer: unbalanced RCU read-side lock on error
[lttng-tools.git] / src / common / consumer / consumer-stream.c
index 1e4b9c92a8813746a3e988a18b7c49d6c22beb8c..ad0f7024d524f4d82d076d3963d086c93e607b89 100644 (file)
@@ -369,7 +369,7 @@ int consumer_stream_sync_metadata(struct lttng_consumer_local_data *ctx,
        assert(ctx);
 
        /* Ease our life a bit. */
-       ht = consumer_data.stream_list_ht;
+       ht = the_consumer_data.stream_list_ht;
 
        rcu_read_lock();
 
@@ -629,13 +629,14 @@ struct lttng_consumer_stream *consumer_stream_create(
                goto end;
        }
 
+       rcu_read_lock();
+
        if (trace_chunk && !lttng_trace_chunk_get(trace_chunk)) {
                ERR("Failed to acquire trace chunk reference during the creation of a stream");
                ret = -1;
                goto error;
        }
 
-       rcu_read_lock();
        stream->chan = channel;
        stream->key = stream_key;
        stream->trace_chunk = trace_chunk;
@@ -817,7 +818,7 @@ void consumer_stream_close(struct lttng_consumer_stream *stream)
 
        assert(stream);
 
-       switch (consumer_data.type) {
+       switch (the_consumer_data.type) {
        case LTTNG_CONSUMER_KERNEL:
                if (stream->mmap_base != NULL) {
                        ret = munmap(stream->mmap_base, stream->mmap_len);
@@ -925,19 +926,19 @@ void consumer_stream_delete(struct lttng_consumer_stream *stream,
         * that did not add the stream to a (all) hash table. Same goes for the
         * next call ht del call.
         */
-       (void) lttng_ht_del(consumer_data.stream_per_chan_id_ht, &iter);
+       (void) lttng_ht_del(the_consumer_data.stream_per_chan_id_ht, &iter);
 
        /* Delete from the global stream list. */
        iter.iter.node = &stream->node_session_id.node;
        /* See the previous ht del on why we ignore the returned value. */
-       (void) lttng_ht_del(consumer_data.stream_list_ht, &iter);
+       (void) lttng_ht_del(the_consumer_data.stream_list_ht, &iter);
 
        rcu_read_unlock();
 
        if (!stream->metadata_flag) {
                /* Decrement the stream count of the global consumer data. */
-               assert(consumer_data.stream_count > 0);
-               consumer_data.stream_count--;
+               assert(the_consumer_data.stream_count > 0);
+               the_consumer_data.stream_count--;
        }
 }
 
@@ -959,7 +960,7 @@ void consumer_stream_destroy_buffers(struct lttng_consumer_stream *stream)
 {
        assert(stream);
 
-       switch (consumer_data.type) {
+       switch (the_consumer_data.type) {
        case LTTNG_CONSUMER_KERNEL:
                break;
        case LTTNG_CONSUMER32_UST:
@@ -1031,7 +1032,7 @@ void consumer_stream_destroy(struct lttng_consumer_stream *stream,
                 * stream thus being globally visible.
                 */
                if (stream->globally_visible) {
-                       pthread_mutex_lock(&consumer_data.lock);
+                       pthread_mutex_lock(&the_consumer_data.lock);
                        pthread_mutex_lock(&stream->chan->lock);
                        pthread_mutex_lock(&stream->lock);
                        /* Remove every reference of the stream in the consumer. */
@@ -1043,11 +1044,11 @@ void consumer_stream_destroy(struct lttng_consumer_stream *stream,
                        free_chan = unref_channel(stream);
 
                        /* Indicates that the consumer data state MUST be updated after this. */
-                       consumer_data.need_update = 1;
+                       the_consumer_data.need_update = 1;
 
                        pthread_mutex_unlock(&stream->lock);
                        pthread_mutex_unlock(&stream->chan->lock);
-                       pthread_mutex_unlock(&consumer_data.lock);
+                       pthread_mutex_unlock(&the_consumer_data.lock);
                } else {
                        /*
                         * If the stream is not visible globally, this needs to be done
@@ -1150,16 +1151,16 @@ int consumer_stream_create_output_files(struct lttng_consumer_stream *stream,
                        goto end;
                }
                stream->out_fd = -1;
-        }
+       }
 
        DBG("Opening stream output file \"%s\"", stream_path);
        chunk_status = lttng_trace_chunk_open_file(stream->trace_chunk, stream_path,
                        flags, mode, &stream->out_fd, false);
-        if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+       if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
                ERR("Failed to open stream file \"%s\"", stream->name);
                ret = -1;
                goto end;
-        }
+       }
 
        if (!stream->metadata_flag && (create_index || stream->index_file)) {
                if (stream->index_file) {
@@ -1289,7 +1290,7 @@ int consumer_stream_flush_buffer(struct lttng_consumer_stream *stream,
 {
        int ret = 0;
 
-       switch (consumer_data.type) {
+       switch (the_consumer_data.type) {
        case LTTNG_CONSUMER_KERNEL:
                if (producer_active) {
                        ret = kernctl_buffer_flush(stream->wait_fd);
@@ -1317,7 +1318,7 @@ int consumer_stream_flush_buffer(struct lttng_consumer_stream *stream,
                break;
        case LTTNG_CONSUMER32_UST:
        case LTTNG_CONSUMER64_UST:
-               lttng_ustconsumer_flush_buffer(stream, (int) producer_active);
+               ret = lttng_ustconsumer_flush_buffer(stream, (int) producer_active);
                break;
        default:
                ERR("Unknown consumer_data type");
This page took 0.027794 seconds and 5 git commands to generate.