From: Mathieu Desnoyers Date: Thu, 25 Apr 2013 18:45:17 +0000 (-0400) Subject: Fix: consumer metadata switch timer error handling X-Git-Tag: v2.2.0-rc2~38 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=4419b4fb187cb896a8e64bb97c5471240abca122;p=lttng-tools.git 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 --- 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;