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;
-}
-
/*
* Flush channel's streams using the given key to retrieve the channel.
*
* 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;
goto end_free;
}
- /*
- * XXX: The consumer data lock is acquired before calling metadata cache
- * write which calls push metadata that MUST be protected by the consumer
- * lock in order to be able to check the validity of the metadata stream of
- * the channel.
- *
- * Note that this will be subject to change to better fine grained locking
- * and ultimately try to get rid of this global consumer data lock.
- */
- pthread_mutex_lock(&consumer_data.lock);
- pthread_mutex_lock(&channel->lock);
pthread_mutex_lock(&channel->metadata_cache->lock);
ret = consumer_metadata_cache_write(channel, offset, len, metadata_str);
if (ret < 0) {
* waiting for the metadata cache to be flushed.
*/
pthread_mutex_unlock(&channel->metadata_cache->lock);
- pthread_mutex_unlock(&channel->lock);
- pthread_mutex_unlock(&consumer_data.lock);
goto end_free;
}
pthread_mutex_unlock(&channel->metadata_cache->lock);
- pthread_mutex_unlock(&channel->lock);
- pthread_mutex_unlock(&consumer_data.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