Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-11-09 07:10:22 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-11-09 07:10:22 +0400
commitf171d0f29c1394795c0a1dea2cb5118859e9ccdc (patch)
tree7836b2214cafec9a04effc7de8560eda74bcc9db
parent1c3640997c225d9bcd6e7559863d69366edc16ee (diff)
Fix #33125: cycles OSL crash with multiple render sessions running at the same time.
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h5
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp23
-rw-r--r--intern/cycles/render/osl.cpp16
-rw-r--r--intern/cycles/render/osl.h2
4 files changed, 42 insertions, 4 deletions
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 5d557ffcb07..80ced9dfd62 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -68,6 +68,11 @@ struct OSLGlobals {
};
static tls_ptr(ThreadData, thread_data);
+ static thread_mutex thread_data_mutex;
+ static volatile int thread_data_users;
+
+ void thread_data_init();
+ void thread_data_free();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 0c8de058b5b..abf7c041cb3 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -32,9 +32,32 @@
CCL_NAMESPACE_BEGIN
tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data);
+volatile int OSLGlobals::thread_data_users = 0;
+thread_mutex OSLGlobals::thread_data_mutex;
/* Threads */
+void OSLGlobals::thread_data_init()
+{
+ thread_scoped_lock thread_data_lock(thread_data_mutex);
+
+ if(thread_data_users == 0)
+ tls_create(OSLGlobals::ThreadData, thread_data);
+
+ thread_data_users++;
+}
+
+void OSLGlobals::thread_data_free()
+{
+ /* thread local storage delete */
+ thread_scoped_lock thread_data_lock(thread_data_mutex);
+
+ thread_data_users--;
+
+ if(thread_data_users == 0)
+ tls_delete(OSLGlobals::ThreadData, thread_data);
+}
+
void OSLShader::thread_init(KernelGlobals *kg)
{
OSL::ShadingSystem *ss = kg->osl.ss;
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 8bdb09eaf70..5fbc7932849 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -45,6 +45,8 @@ CCL_NAMESPACE_BEGIN
OSLShaderManager::OSLShaderManager()
{
+ thread_data_initialized = false;
+
services = new OSLRenderServices();
shading_system_init();
@@ -91,8 +93,6 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
og->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true;
- tls_create(OSLGlobals::ThreadData, og->thread_data);
-
foreach(Shader *shader, scene->shaders)
shader->need_update = false;
@@ -102,6 +102,11 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
scene->image_manager->set_osl_texture_system((void*)ts);
device_update_common(device, dscene, scene, progress);
+
+ if(!thread_data_initialized) {
+ og->thread_data_init();
+ thread_data_initialized = true;
+ }
}
void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
@@ -114,12 +119,15 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
og->use = false;
og->ss = NULL;
- tls_delete(OSLGlobals::ThreadData, og->thread_data);
-
og->surface_state.clear();
og->volume_state.clear();
og->displacement_state.clear();
og->background_state.reset();
+
+ if(thread_data_initialized) {
+ og->thread_data_free();
+ thread_data_initialized = false;
+ }
}
void OSLShaderManager::texture_system_init()
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index cee37c58d74..b4b3f59e02a 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -73,6 +73,8 @@ protected:
OSLRenderServices *services;
OSL::ErrorHandler errhandler;
set<string> loaded_shaders;
+
+ bool thread_data_initialized;
};
#endif