/* Get the right pipe where the stream will be sent. */
if (stream->metadata_flag) {
+ ret = consumer_add_metadata_stream(stream);
+ if (ret) {
+ ERR("Consumer add metadata stream %" PRIu64 " failed.",
+ stream->key);
+ goto error;
+ }
stream_pipe = ctx->consumer_metadata_pipe;
} else {
+ ret = consumer_add_data_stream(stream);
+ if (ret) {
+ ERR("Consumer add stream %" PRIu64 " failed.",
+ stream->key);
+ goto error;
+ }
stream_pipe = ctx->consumer_data_pipe;
}
+ /*
+ * From this point on, the stream's ownership has been moved away from
+ * the channel and becomes globally visible.
+ */
+ stream->globally_visible = 1;
+
ret = lttng_pipe_write(stream_pipe, &stream, sizeof(stream));
if (ret < 0) {
ERR("Consumer write %s stream to pipe %d",
stream->metadata_flag ? "metadata" : "data",
lttng_pipe_get_writefd(stream_pipe));
+ if (stream->metadata_flag) {
+ consumer_del_stream_for_metadata(stream);
+ } else {
+ consumer_del_stream_for_data(stream);
+ }
}
-
+error:
return ret;
}
* If we are unable to send the stream to the thread, there is
* a big problem so just stop everything.
*/
+ /* Remove node from the channel stream list. */
+ cds_list_del(&stream->send_node);
goto error;
}
/* Remove node from the channel stream list. */
cds_list_del(&stream->send_node);
- /*
- * From this point on, the stream's ownership has been moved away from
- * the channel and becomes globally visible.
- */
- stream->globally_visible = 1;
- }
-
-error:
- return ret;
-}
-
-/*
- * Write metadata to the given channel using ustctl to convert the string to
- * the ringbuffer.
- * Called only from consumer_metadata_cache_write.
- * The metadata cache lock MUST be acquired to write in the cache.
- *
- * Return 0 on success else a negative value.
- */
-int lttng_ustconsumer_push_metadata(struct lttng_consumer_channel *metadata,
- const char *metadata_str, uint64_t target_offset, uint64_t len)
-{
- int ret;
-
- assert(metadata);
- assert(metadata_str);
-
- DBG("UST consumer writing metadata to channel %s", metadata->name);
-
- if (!metadata->metadata_stream) {
- ret = 0;
- goto error;
- }
-
- assert(target_offset <= metadata->metadata_cache->max_offset);
- ret = ustctl_write_metadata_to_channel(metadata->uchan,
- metadata_str + target_offset, len);
- if (ret < 0) {
- ERR("ustctl write metadata fail with ret %d, len %" PRIu64, ret, len);
- goto error;
}
- ustctl_flush_buffer(metadata->metadata_stream->ustream, 1);
-
error:
return ret;
}
cds_lfht_for_each_entry_duplicate(ht->ht,
ht->hash_fct(&channel->key, lttng_ht_seed), ht->match_fct,
&channel->key, &iter.iter, stream, node_channel_id.node) {
- ustctl_flush_buffer(stream->ustream, 1);
+ ustctl_flush_buffer(stream->ustream, 1);
}
error:
rcu_read_unlock();
* Ask the sessiond if we have new metadata waiting and update the
* consumer metadata cache.
*/
- ret = lttng_ustconsumer_request_metadata(ctx, metadata_channel);
+ ret = lttng_ustconsumer_request_metadata(ctx, metadata_channel, 0);
if (ret < 0) {
goto error;
}
* Receive the metadata updates from the sessiond.
*/
int lttng_ustconsumer_recv_metadata(int sock, uint64_t key, uint64_t offset,
- uint64_t len, struct lttng_consumer_channel *channel)
+ uint64_t len, struct lttng_consumer_channel *channel,
+ int timer)
{
int ret, ret_code = LTTNG_OK;
char *metadata_str;
}
pthread_mutex_unlock(&channel->metadata_cache->lock);
- while (consumer_metadata_cache_flushed(channel, offset + len)) {
+ while (consumer_metadata_cache_flushed(channel, offset + len, timer)) {
DBG("Waiting for metadata to be flushed");
usleep(DEFAULT_METADATA_AVAILABILITY_WAIT_TIME);
}
}
ret = lttng_ustconsumer_recv_metadata(sock, key, offset,
- len, channel);
+ len, channel, 0);
if (ret < 0) {
/* error receiving from sessiond */
goto error_fatal;
}
}
+/*
+ * Please refer to consumer-timer.c before adding any lock within this
+ * function or any of its callees. Timers have a very strict locking
+ * semantic with respect to teardown. Failure to respect this semantic
+ * introduces deadlocks.
+ */
int lttng_ustconsumer_request_metadata(struct lttng_consumer_local_data *ctx,
- struct lttng_consumer_channel *channel)
+ struct lttng_consumer_channel *channel, int timer)
{
struct lttcomm_metadata_request_msg request;
struct lttcomm_consumer_msg msg;
}
ret_code = lttng_ustconsumer_recv_metadata(ctx->consumer_metadata_socket,
- key, offset, len, channel);
+ key, offset, len, channel, timer);
if (ret_code >= 0) {
/*
* Only send the status msg if the sessiond is alive meaning a positive