Fix #29084: material/texture nodes crash introduced in 2.60, execdata is being
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 31 Oct 2011 17:00:59 +0000 (17:00 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 31 Oct 2011 17:00:59 +0000 (17:00 +0000)
lazely created but this wasn't done in a thread safe way.

source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/threads.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/nodes/texture/node_texture_tree.c

index 00d8131..8826e9a 100644 (file)
@@ -70,6 +70,7 @@ int           BLI_system_thread_count(void); /* gets the number of threads the system can
 #define LOCK_CUSTOM1   3
 #define LOCK_RCACHE            4
 #define LOCK_OPENGL            5
+#define LOCK_NODES             6
 
 void   BLI_lock_thread(int type);
 void   BLI_unlock_thread(int type);
index c049ab8..7b156a3 100644 (file)
@@ -113,6 +113,7 @@ static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_t mainid;
 static int thread_levels= 0;   /* threads can be invoked inside threads */
 
@@ -347,6 +348,8 @@ void BLI_lock_thread(int type)
                pthread_mutex_lock(&_rcache_lock);
        else if (type==LOCK_OPENGL)
                pthread_mutex_lock(&_opengl_lock);
+       else if (type==LOCK_NODES)
+               pthread_mutex_lock(&_nodes_lock);
 }
 
 void BLI_unlock_thread(int type)
@@ -363,6 +366,8 @@ void BLI_unlock_thread(int type)
                pthread_mutex_unlock(&_rcache_lock);
        else if(type==LOCK_OPENGL)
                pthread_mutex_unlock(&_opengl_lock);
+       else if(type==LOCK_NODES)
+               pthread_mutex_unlock(&_nodes_lock);
 }
 
 /* Mutex Locks */
index cc8e161..a83b320 100644 (file)
@@ -212,8 +212,15 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
        /* each material node has own local shaderesult, with optional copying */
        memset(shr, 0, sizeof(ShadeResult));
        
-       if (!exec)
-               exec = ntree->execdata = ntreeShaderBeginExecTree(ntree, 1);
+       /* ensure execdata is only initialized once */
+       if (!exec) {
+               BLI_lock_thread(LOCK_NODES);
+               if(!ntree->execdata)
+                       ntree->execdata = ntreeShaderBeginExecTree(ntree, 1);
+               BLI_unlock_thread(LOCK_NODES);
+
+               exec = ntree->execdata;
+       }
        
        nts= ntreeGetThreadStack(exec, shi->thread);
        ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
index 7879295..5e5d445 100644 (file)
@@ -232,8 +232,15 @@ int ntreeTexExecTree(
        data.mtex= mtex;
        data.shi= shi;
        
-       if (!exec)
-               exec = ntreeTexBeginExecTree(nodes, 1);
+       /* ensure execdata is only initialized once */
+       if (!exec) {
+               BLI_lock_thread(LOCK_NODES);
+               if(!nodes->execdata)
+                       ntreeTexBeginExecTree(nodes, 1);
+               BLI_unlock_thread(LOCK_NODES);
+
+               exec= nodes->execdata;
+       }
        
        nts= ntreeGetThreadStack(exec, thread);
        ntreeExecThreadNodes(exec, nts, &data, thread);