From 63b5fb1b30b779a42e9e23a67a26366ac4afcd91 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 10 Sep 2013 14:55:42 -0700 Subject: [PATCH] glsl: Add locking to builtin_builder::initialize(). Consider a multithreaded program with two contexts A and B, and the following scenario: 1. Context A calls initialize(), which allocates mem_ctx and starts building built-ins. 2. Context B calls initialize(), which sees mem_ctx != NULL and assumes everything is already set up. It returns. 3. Context B calls find(), which fails to find the built-in since it hasn't been created yet. 4. Context A finally finishes initializing the built-ins. This will break at step 3. Adding a lock ensures that subsequent callers of initialize() will wait until initialization is actually complete. Fixes sporadic failures in Piglit's glx-multithread-shader-compile. Signed-off-by: Kenneth Graunke --- src/glsl/builtin_functions.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index ce78df1..bc539ef 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -565,13 +565,16 @@ builtin_builder::find(_mesa_glsl_parse_state *state, void builtin_builder::initialize() { - /* If already initialized, don't do it again. */ - if (mem_ctx != NULL) - return; + _glthread_DECLARE_STATIC_MUTEX(builtin_init_lock); + _glthread_LOCK_MUTEX(builtin_init_lock); - mem_ctx = ralloc_context(NULL); - create_shader(); - create_builtins(); + if (mem_ctx == NULL) { + mem_ctx = ralloc_context(NULL); + create_shader(); + create_builtins(); + } + + _glthread_UNLOCK_MUTEX(builtin_init_lock); } void -- 1.8.3.4