From 4419b4fb187cb896a8e64bb97c5471240abca122 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 25 Apr 2013 14:45:17 -0400 Subject: [PATCH] Fix: consumer metadata switch timer error handling The thread handling the metadata switch cannot call consumer_timer_switch_stop(), because it would become stucked waiting for itself to execute the teardown signal handler. Moreover, only one thread is allowed to call start/stop timer (by design). Therefore, it's a race to have the thread handling the timer handler calling "stop". Fix this by adding a "switch_timer_error" flag, which just inhibits the timer if an error is encountered, but does not modify its state otherwise. Signed-off-by: Mathieu Desnoyers Signed-off-by: David Goulet --- src/common/consumer-timer.c | 14 +++++++++----- src/common/consumer.h | 2 ++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/common/consumer-timer.c b/src/common/consumer-timer.c index ef056d118..641478697 100644 --- a/src/common/consumer-timer.c +++ b/src/common/consumer-timer.c @@ -61,17 +61,17 @@ static void metadata_switch_timer(struct lttng_consumer_local_data *ctx, channel = si->si_value.sival_ptr; assert(channel); + if (channel->switch_timer_error) { + return; + } + DBG("Switch timer for channel %" PRIu64, channel->key); switch (ctx->type) { case LTTNG_CONSUMER32_UST: case LTTNG_CONSUMER64_UST: ret = lttng_ustconsumer_request_metadata(ctx, channel); if (ret < 0) { - /* - * An error means that we were unable to request the metadata to - * the session daemon so stop the timer for that channel. - */ - consumer_timer_switch_stop(channel); + channel->switch_timer_error = 1; } break; case LTTNG_CONSUMER_KERNEL: @@ -83,6 +83,8 @@ static void metadata_switch_timer(struct lttng_consumer_local_data *ctx, /* * Set the timer for periodical metadata flush. + * Should be called only from the recv cmd thread (single thread ensures + * mutual exclusion). */ void consumer_timer_switch_start(struct lttng_consumer_channel *channel, unsigned int switch_timer_interval) @@ -120,6 +122,8 @@ void consumer_timer_switch_start(struct lttng_consumer_channel *channel, /* * Stop and delete timer. + * Should be called only from the recv cmd thread (single thread ensures + * mutual exclusion). */ void consumer_timer_switch_stop(struct lttng_consumer_channel *channel) { diff --git a/src/common/consumer.h b/src/common/consumer.h index 19a590e80..844310681 100644 --- a/src/common/consumer.h +++ b/src/common/consumer.h @@ -146,6 +146,8 @@ struct lttng_consumer_channel { /* For metadata periodical flush */ int switch_timer_enabled; timer_t switch_timer; + int switch_timer_error; + /* On-disk circular buffer */ uint64_t tracefile_size; uint64_t tracefile_count; -- 2.34.1