projects
/
lttng-ust.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Add critical log level
[lttng-ust.git]
/
src
/
common
/
getenv.c
diff --git
a/src/common/getenv.c
b/src/common/getenv.c
index 23029508b161d126590d8ed3bbcc943e0e23aa8c..55e6ad7cc5a069130ffb2172890752ef3e0d22c6 100644
(file)
--- a/
src/common/getenv.c
+++ b/
src/common/getenv.c
@@
-9,6
+9,7
@@
#include <stdbool.h>
#include <stddef.h>
#include <sys/types.h>
#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"
#include <urcu/system.h>
#include "common/logging.h"
#include "common/macros.h"
@@
-25,16
+26,18
@@
struct lttng_env {
char *value;
};
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[] = {
/*
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_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, },
/* Env. var. which can be used in setuid/setgid executables. */
{ "LTTNG_UST_WITHOUT_BADDR_STATEDUMP", LTTNG_ENV_NOT_SECURE, NULL, },
@@
-88,8
+91,25
@@
void lttng_ust_getenv_init(void)
{
size_t i;
{
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;
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];
for (i = 0; i < LTTNG_ARRAY_SIZE(lttng_env); i++) {
struct lttng_env *e = <tng_env[i];
@@
-101,5
+121,12
@@
void lttng_ust_getenv_init(void)
}
e->value = getenv(e->key);
}
}
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);
CMM_STORE_SHARED(lttng_ust_getenv_is_init, 1);
+end_init:
+ pthread_mutex_unlock(<tng_ust_getenv_init_mutex);
}
}
This page took
0.025282 seconds
and
4
git commands to generate.