From: Jason Wessel Date: Wed, 27 Apr 2011 20:22:15 +0000 (+0200) Subject: ust-consumerd: fix exit race log corruption X-Git-Tag: v0.13~10 X-Git-Url: http://git.liburcu.org/?p=ust.git;a=commitdiff_plain;h=ebb0b9c112a0583504922a9451571b648d67a6de ust-consumerd: fix exit race log corruption In the following scenario on an SMP system the ust-consumerd can end up not properly closing out file handles which leads to log corruption: * usttrace -m -l small_quick_app_lots_of_malloc_and_free * The app completes and usttrace sees and sends the SIGTERM to ust-consumerd * The ust-consumerd main thread will exit and the _exit() handlers kills off the remaining pthreads without everything getting closed out The solution to the problem is to introduce an active_thread count for the private ustconsumer_instance. This counter will be zeroed out when it is safe to completely shutdown the main thread, which will subsequently run the _exit() handlers. Signed-off-by: Jason Wessel Signed-off-by: Nils Carlson --- diff --git a/include/ust/ustconsumer.h b/include/ust/ustconsumer.h index f99f8f1..cde8440 100644 --- a/include/ust/ustconsumer.h +++ b/include/ust/ustconsumer.h @@ -89,6 +89,7 @@ struct ustconsumer_instance { char *sock_path; pthread_mutex_t mutex; int active_buffers; + int active_threads; }; /** diff --git a/libustconsumer/libustconsumer.c b/libustconsumer/libustconsumer.c index abf21d8..b47f04a 100644 --- a/libustconsumer/libustconsumer.c +++ b/libustconsumer/libustconsumer.c @@ -543,6 +543,10 @@ void *consumer_thread(void *arg) int result; sigset_t sigset; + pthread_mutex_lock(&args->instance->mutex); + args->instance->active_threads++; + pthread_mutex_unlock(&args->instance->mutex); + if(args->instance->callbacks->on_new_thread) args->instance->callbacks->on_new_thread(args->instance->callbacks); @@ -584,6 +588,10 @@ void *consumer_thread(void *arg) if(args->instance->callbacks->on_close_thread) args->instance->callbacks->on_close_thread(args->instance->callbacks); + pthread_mutex_lock(&args->instance->mutex); + args->instance->active_threads--; + pthread_mutex_unlock(&args->instance->mutex); + free((void *)args->channel); free(args); return NULL; @@ -735,7 +743,7 @@ int ustconsumer_start_instance(struct ustconsumer_instance *instance) if (instance->quit_program) { pthread_mutex_lock(&instance->mutex); - if(instance->active_buffers == 0) { + if (instance->active_buffers == 0 && instance->active_threads == 0) { pthread_mutex_unlock(&instance->mutex); break; }