[Mesa-dev] [PATCH 02/21] glsl: protect locale_t with a mutex

Ian Romanick idr at freedesktop.org
Fri May 2 10:52:01 PDT 2014


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 <olv at lunarg.com>
> ---
>  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);
>  
> 



More information about the mesa-dev mailing list