On 04/22/2014 01:58 AM, Chia-I Wu wrote: > There may be two contexts compiling shaders at the same time. locale_t needs > to be protected.
Rather than calling glsl_initialize_strtod from other places in the compiler, it seems better to use call_once from the strtof and strtod functions. > 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); > > _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
