From 042dbbc86aaf0d25b4922ecf268f406d31cd8986 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 16 Apr 2021 12:02:01 -0400 Subject: [PATCH] getenv: make getenv helper init state mt-safe Change-Id: Idebb709fe4dd5501dfe657ea23fc6a67a65ce1ff Signed-off-by: Mathieu Desnoyers --- src/common/getenv.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/common/getenv.c b/src/common/getenv.c index 23029508..bc7a4d4a 100644 --- a/src/common/getenv.c +++ b/src/common/getenv.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "common/logging.h" #include "common/macros.h" @@ -25,8 +26,9 @@ struct lttng_env { char *value; }; -static -int lttng_ust_getenv_is_init = 0; +/* lttng_ust_getenv_init_mutex provides mutual exclusion for initialization. */ +static pthread_mutex_t lttng_ust_getenv_init_mutex = PTHREAD_MUTEX_INITIALIZER; +static int lttng_ust_getenv_is_init = 0; static struct lttng_env lttng_env[] = { /* @@ -88,8 +90,25 @@ void lttng_ust_getenv_init(void) { size_t i; - if (CMM_LOAD_SHARED(lttng_ust_getenv_is_init)) + /* + * Return early if the init has already completed. + */ + if (CMM_LOAD_SHARED(lttng_ust_getenv_is_init)) { + /* + * Load lttng_ust_getenv_is_init before reading environment cache. + */ + cmm_smp_rmb(); return; + } + + pthread_mutex_lock(<tng_ust_getenv_init_mutex); + + /* + * Check again if the init has completed in another thread now that we + * have acquired the mutex. + */ + if (lttng_ust_getenv_is_init) + goto end_init; for (i = 0; i < LTTNG_ARRAY_SIZE(lttng_env); i++) { struct lttng_env *e = <tng_env[i]; @@ -101,5 +120,12 @@ void lttng_ust_getenv_init(void) } e->value = getenv(e->key); } + + /* + * Store environment cache before setting lttng_ust_getenv_is_init to 1. + */ + cmm_smp_wmb(); CMM_STORE_SHARED(lttng_ust_getenv_is_init, 1); +end_init: + pthread_mutex_unlock(<tng_ust_getenv_init_mutex); } -- 2.34.1