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

Chia-I Wu olvaffe at gmail.com
Tue Apr 22 01:58:17 PDT 2014


There may be two contexts compiling shaders at the same time.  locale_t needs
to be protected.

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);
 
-- 
1.8.5.3



More information about the mesa-dev mailing list