Fix #33125: cycles OSL crash with multiple render sessions running at the same time.

This commit is contained in:
Brecht Van Lommel
2012-11-09 03:10:22 +00:00
parent 1c3640997c
commit f171d0f29c
4 changed files with 42 additions and 4 deletions

View File

@@ -68,6 +68,11 @@ struct OSLGlobals {
}; };
static tls_ptr(ThreadData, thread_data); 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 CCL_NAMESPACE_END

View File

@@ -32,9 +32,32 @@
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data); tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data);
volatile int OSLGlobals::thread_data_users = 0;
thread_mutex OSLGlobals::thread_data_mutex;
/* Threads */ /* 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) void OSLShader::thread_init(KernelGlobals *kg)
{ {
OSL::ShadingSystem *ss = kg->osl.ss; OSL::ShadingSystem *ss = kg->osl.ss;

View File

@@ -45,6 +45,8 @@ CCL_NAMESPACE_BEGIN
OSLShaderManager::OSLShaderManager() OSLShaderManager::OSLShaderManager()
{ {
thread_data_initialized = false;
services = new OSLRenderServices(); services = new OSLRenderServices();
shading_system_init(); 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->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true; og->use = true;
tls_create(OSLGlobals::ThreadData, og->thread_data);
foreach(Shader *shader, scene->shaders) foreach(Shader *shader, scene->shaders)
shader->need_update = false; 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); scene->image_manager->set_osl_texture_system((void*)ts);
device_update_common(device, dscene, scene, progress); 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) void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
@@ -114,12 +119,15 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
og->use = false; og->use = false;
og->ss = NULL; og->ss = NULL;
tls_delete(OSLGlobals::ThreadData, og->thread_data);
og->surface_state.clear(); og->surface_state.clear();
og->volume_state.clear(); og->volume_state.clear();
og->displacement_state.clear(); og->displacement_state.clear();
og->background_state.reset(); og->background_state.reset();
if(thread_data_initialized) {
og->thread_data_free();
thread_data_initialized = false;
}
} }
void OSLShaderManager::texture_system_init() void OSLShaderManager::texture_system_init()

View File

@@ -73,6 +73,8 @@ protected:
OSLRenderServices *services; OSLRenderServices *services;
OSL::ErrorHandler errhandler; OSL::ErrorHandler errhandler;
set<string> loaded_shaders; set<string> loaded_shaders;
bool thread_data_initialized;
}; };
#endif #endif