There may be two contexts compiling shaders at the same time. locale_t needs to be protected.
Signed-off-by: Chia-I Wu <[email protected]> --- src/glsl/glsl_lexer.ll | 1 + src/glsl/ir_reader.cpp | 2 ++ src/glsl/strtod.c | 36 ++++++++++++++++++++++++------------ src/glsl/strtod.h | 3 +++ 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index 7602351..eb23120 100644 --- a/src/glsl/glsl_lexer.ll +++ b/src/glsl/glsl_lexer.ll @@ -567,6 +567,7 @@ classify_identifier(struct _mesa_glsl_parse_state *state, const char *name) void _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string) { + glsl_initialize_strtod(); yylex_init_extra(state, & state->scanner); yy_scan_string(string, state->scanner); } diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 28923f3..38b445b 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -79,6 +79,8 @@ void _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, const char *src, bool scan_for_protos) { + glsl_initialize_strtod(); + ir_reader r(state); r.read(instructions, src, scan_for_protos); } diff --git a/src/glsl/strtod.c b/src/glsl/strtod.c index 5d4346b..f37b3f5 100644 --- a/src/glsl/strtod.c +++ b/src/glsl/strtod.c @@ -25,6 +25,7 @@ #include <stdlib.h> +#include "c11/threads.h" #ifdef _GNU_SOURCE #include <locale.h> @@ -35,6 +36,27 @@ #include "strtod.h" +#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \ + !defined(__HAIKU__) && !defined(__UCLIBC__) +#define GLSL_HAVE_LOCALE_T +#endif + +#ifdef GLSL_HAVE_LOCALE_T +static mtx_t loc_lock = _MTX_INITIALIZER_NP; +static locale_t loc = NULL; +#endif + +void +glsl_initialize_strtod(void) +{ +#ifdef GLSL_HAVE_LOCALE_T + mtx_lock(&loc_lock); + if (!loc) + loc = newlocale(LC_CTYPE_MASK, "C", NULL); + mtx_unlock(&loc_lock); +#endif +} + /** @@ -44,12 +66,7 @@ double glsl_strtod(const char *s, char **end) { -#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \ - !defined(__HAIKU__) && !defined(__UCLIBC__) - static locale_t loc = NULL; - if (!loc) { - loc = newlocale(LC_CTYPE_MASK, "C", NULL); - } +#ifdef GLSL_HAVE_LOCALE_T return strtod_l(s, end, loc); #else return strtod(s, end); @@ -64,12 +81,7 @@ glsl_strtod(const char *s, char **end) float glsl_strtof(const char *s, char **end) { -#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \ - !defined(__HAIKU__) && !defined(__UCLIBC__) - static locale_t loc = NULL; - if (!loc) { - loc = newlocale(LC_CTYPE_MASK, "C", NULL); - } +#ifdef GLSL_HAVE_LOCALE_T return strtof_l(s, end, loc); #elif _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE return strtof(s, end); diff --git a/src/glsl/strtod.h b/src/glsl/strtod.h index ad847db..8062928 100644 --- a/src/glsl/strtod.h +++ b/src/glsl/strtod.h @@ -31,6 +31,9 @@ extern "C" { #endif +extern void +glsl_initialize_strtod(void); + extern double glsl_strtod(const char *s, char **end); -- 1.8.5.3 _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
