ust-fd: Add close_range declaration
[lttng-ust.git] / src / common / getenv.c
index 1909f4cf912bd8f80ebf51e6fc5dd88bb866607c..120225e6bc888104262856849ea9a51fcb71151d 100644 (file)
@@ -9,6 +9,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <sys/types.h>
+#include <pthread.h>
 #include <urcu/system.h>
 #include "common/logging.h"
 #include "common/macros.h"
@@ -25,20 +26,23 @@ 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[] = {
        /*
-        * LTTNG_UST_DEBUG is used directly by snprintf, because it
-        * needs to be already set for ERR() used in
-        * lttng_ust_getenv_init().
+        * LTTNG_UST_DEBUG and LTTNG_UST_ABORT_ON_CRITICAL are used directly by
+        * the internal logging, because they need to be already set for ERR()
+        * used in lttng_ust_getenv_init().
         */
        { "LTTNG_UST_DEBUG", LTTNG_ENV_NOT_SECURE, NULL, },
+       { "LTTNG_UST_ABORT_ON_CRITICAL", LTTNG_ENV_NOT_SECURE, NULL, },
 
        /* Env. var. which can be used in setuid/setgid executables. */
        { "LTTNG_UST_WITHOUT_BADDR_STATEDUMP", LTTNG_ENV_NOT_SECURE, NULL, },
        { "LTTNG_UST_REGISTER_TIMEOUT", LTTNG_ENV_NOT_SECURE, NULL, },
+       { "LTTNG_UST_MAP_POPULATE_POLICY", LTTNG_ENV_NOT_SECURE, NULL, },
 
        /* Env. var. which are not fetched in setuid/setgid executables. */
        { "LTTNG_UST_CLOCK_PLUGIN", LTTNG_ENV_SECURE, NULL, },
@@ -46,6 +50,7 @@ static struct lttng_env lttng_env[] = {
        { "LTTNG_UST_ALLOW_BLOCKING", LTTNG_ENV_SECURE, NULL, },
        { "HOME", LTTNG_ENV_SECURE, NULL, },
        { "LTTNG_HOME", LTTNG_ENV_SECURE, NULL, },
+       { "LTTNG_UST_APP_PATH", LTTNG_ENV_SECURE, NULL, },
 };
 
 static
@@ -64,8 +69,11 @@ char *lttng_ust_getenv(const char *name)
        struct lttng_env *e;
        bool found = false;
 
-       if (!CMM_LOAD_SHARED(lttng_ust_getenv_is_init))
-               abort();
+       /*
+        * Perform lazy initialization of lttng_ust_getenv for early use
+        * by library constructors.
+        */
+       lttng_ust_getenv_init();
 
        for (i = 0; i < LTTNG_ARRAY_SIZE(lttng_env); i++) {
                e = &lttng_env[i];
@@ -85,8 +93,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(&lttng_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 = &lttng_env[i];
@@ -98,5 +123,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(&lttng_ust_getenv_init_mutex);
 }
This page took 0.023901 seconds and 4 git commands to generate.