diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-09 07:10:22 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-09 07:10:22 +0400 |
commit | f171d0f29c1394795c0a1dea2cb5118859e9ccdc (patch) | |
tree | 7836b2214cafec9a04effc7de8560eda74bcc9db | |
parent | 1c3640997c225d9bcd6e7559863d69366edc16ee (diff) |
Fix #33125: cycles OSL crash with multiple render sessions running at the same time.
-rw-r--r-- | intern/cycles/kernel/osl/osl_globals.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_shader.cpp | 23 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 16 | ||||
-rw-r--r-- | intern/cycles/render/osl.h | 2 |
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 |