[Bf-blender-cvs] [0464876] master: Make main library safe(er) for the threaded usage

Sergey Sharybin noreply at git.blender.org
Tue Jun 24 19:35:30 CEST 2014


Commit: 04648767fabda7d9461e32c89afcd806d0227547
Author: Sergey Sharybin
Date:   Tue Jun 24 20:43:08 2014 +0600
https://developer.blender.org/rB04648767fabda7d9461e32c89afcd806d0227547

Make main library safe(er) for the threaded usage

Added a lock to the Main which is getting acquired and released
when modifying it's lists.

Should not be any functional changes now, it just means Main is
now considered safe without worrying about locks in the callee.

===================================================================

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/BKE_main.h
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/node.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 55c71ff..c78ea21 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -77,7 +77,7 @@ int set_listbasepointers(struct Main *main, struct ListBase **lb);
 void BKE_libblock_free(struct Main *bmain, void *idv);
 void BKE_libblock_free_ex(struct Main *bmain, void *idv, bool do_id_user);
 void BKE_libblock_free_us(struct Main *bmain, void *idv);
-void BKE_libblock_free_data(struct ID *id);
+void BKE_libblock_free_data(struct Main *bmain, struct ID *id);
 
 
 /* Main API */
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 721866d..ade5733 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -41,6 +41,7 @@
  *
  */
 #include "DNA_listBase.h"
+#include "BLI_threads.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -96,6 +97,8 @@ typedef struct Main {
 
 	/* Evaluation context used by viewport */
 	struct EvaluationContext *eval_ctx;
+
+	SpinLock lock;
 } Main;
 
 #define MAIN_VERSION_ATLEAST(main, ver, subver) \
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index fe2d148..9a74edb 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -747,12 +747,14 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
 	
 	id = alloc_libblock_notest(type);
 	if (id) {
+		BLI_spin_lock(&bmain->lock);
 		BLI_addtail(lb, id);
 		id->us = 1;
 		id->icon_id = 0;
 		*( (short *)id->name) = type;
 		new_id(lb, id, name);
 		/* alphabetic insertion: is in new_id */
+		BLI_spin_unlock(&bmain->lock);
 	}
 	DAG_id_type_tag(bmain, type);
 	return id;
@@ -881,10 +883,8 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata
 	}
 }
 
-void BKE_libblock_free_data(ID *id)
+void BKE_libblock_free_data(Main *bmain, ID *id)
 {
-	Main *bmain = G.main;  /* should eventually be an arg */
-	
 	if (id->properties) {
 		IDP_FreeProperty(id->properties);
 		MEM_freeN(id->properties);
@@ -1008,12 +1008,15 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 	}
 
 	/* avoid notifying on removed data */
+	BLI_spin_lock(&bmain->lock);
+
 	if (free_notifier_reference_cb)
 		free_notifier_reference_cb(id);
 
 	BLI_remlink(lb, id);
 
-	BKE_libblock_free_data(id);
+	BKE_libblock_free_data(bmain, id);
+	BLI_spin_unlock(&bmain->lock);
 
 	MEM_freeN(id);
 }
@@ -1043,7 +1046,9 @@ void BKE_libblock_free_us(Main *bmain, void *idv)      /* test users */
 Main *BKE_main_new(void)
 {
 	Main *bmain = MEM_callocN(sizeof(Main), "new main");
-	bmain->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "EvaluationContext");
+	bmain->eval_ctx = MEM_callocN(sizeof(EvaluationContext),
+	                              "EvaluationContext");
+	BLI_spin_init(&bmain->lock);
 	return bmain;
 }
 
@@ -1106,6 +1111,7 @@ void BKE_main_free(Main *mainvar)
 		}
 	}
 
+	BLI_spin_end(&mainvar->lock);
 	MEM_freeN(mainvar->eval_ctx);
 	MEM_freeN(mainvar);
 }
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index de3aea9..4f6f234 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -780,11 +780,13 @@ void test_object_materials(Main *bmain, ID *id)
 		return;
 	}
 
+	BLI_spin_lock(&bmain->lock);
 	for (ob = bmain->object.first; ob; ob = ob->id.next) {
 		if (ob->data == id) {
 			BKE_material_resize_object(ob, *totcol, false);
 		}
 	}
+	BLI_spin_unlock(&bmain->lock);
 }
 
 void assign_material_id(ID *id, Material *ma, short act)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 7197d56..7c6164a 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2148,7 +2148,7 @@ Mesh *BKE_mesh_new_from_object(
 			 * if it didn't the curve did not have any segments or otherwise 
 			 * would have generated an empty mesh */
 			if (tmpobj->type != OB_MESH) {
-				BKE_libblock_free_us(G.main, tmpobj);
+				BKE_libblock_free_us(bmain, tmpobj);
 				return NULL;
 			}
 
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index c8632a4..56a76a5 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1777,7 +1777,7 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
 		if (tntree == ntree)
 			break;
 	if (tntree == NULL) {
-		BKE_libblock_free_data(&ntree->id);
+		BKE_libblock_free_data(G.main, &ntree->id);
 	}
 }
 /* same as ntreeFreeTree_ex but always manage users */




More information about the Bf-blender-cvs mailing list