/*
* Execute action on a timer switch.
+ *
+ * Beware: metadata_switch_timer() should *never* take a mutex also held
+ * while consumer_timer_switch_stop() is called. It would result in
+ * deadlocks.
*/
static void metadata_switch_timer(struct lttng_consumer_local_data *ctx,
int sig, siginfo_t *si, void *uc)
switch (ctx->type) {
case LTTNG_CONSUMER32_UST:
case LTTNG_CONSUMER64_UST:
- ret = lttng_ustconsumer_request_metadata(ctx, channel);
+ /*
+ * Locks taken by lttng_ustconsumer_request_metadata():
+ * - metadata_socket_lock
+ * - Calling lttng_ustconsumer_recv_metadata():
+ * - channel->metadata_cache->lock
+ * - Calling consumer_metadata_cache_flushed():
+ * - channel->timer_lock
+ * - channel->metadata_cache->lock
+ *
+ * Ensure that neither consumer_data.lock nor
+ * channel->lock are taken within this function, since
+ * they are held while consumer_timer_switch_stop() is
+ * called.
+ */
+ ret = lttng_ustconsumer_request_metadata(ctx, channel, 1);
if (ret < 0) {
channel->switch_timer_error = 1;
}