[Bf-blender-cvs] [e446935265c] datablock_idprops: Fix always-unlinking in ID free function.

Bastien Montagne noreply at git.blender.org
Thu Mar 30 12:56:40 CEST 2017


Commit: e446935265c08fe0abd19b43134a30c51a84679c
Author: Bastien Montagne
Date:   Thu Mar 30 12:52:07 2017 +0200
Branches: datablock_idprops
https://developer.blender.org/rBe446935265c08fe0abd19b43134a30c51a84679c

Fix always-unlinking in ID free function.

Since IDProps now handle ID usages, makes sense to pass do_id_user flag
to some new IDP_FreeProperty_ex() as well...

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

M	source/blender/blenkernel/BKE_idprop.h
M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/intern/idprop.c
M	source/blender/blenkernel/intern/library_remap.c
M	source/blender/blenkernel/intern/node.c
M	source/blender/windowmanager/intern/wm.c

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

diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index d86075c1317..ab8728faedb 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -60,8 +60,6 @@ typedef union IDPropertyTemplate {
 IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 IDProperty *IDP_CopyIDPArray(const IDProperty *array) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
-void IDP_FreeIDPArray(IDProperty *prop);
-
 /* shallow copies item */
 void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL();
 struct IDProperty *IDP_GetIndexArray(struct IDProperty *prop, int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -112,6 +110,7 @@ bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) AT
 
 struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
+void IDP_FreeProperty_ex(struct IDProperty *prop, const bool do_id_user);
 void IDP_FreeProperty(struct IDProperty *prop);
 
 void IDP_ClearProperty(IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 72ae2cf4efa..6649cfbb585 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -66,7 +66,7 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_
 void  BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
 void  BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
 void  BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
-void  BKE_libblock_free_data(struct Main *bmain, struct ID *id) ATTR_NONNULL();
+void  BKE_libblock_free_data(struct Main *bmain, struct ID *id, const bool do_id_user) ATTR_NONNULL();
 void  BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
 
 void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index e0cf0c686ff..9fae57df501 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -116,14 +116,14 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array)
 	return narray;
 }
 
-void IDP_FreeIDPArray(IDProperty *prop)
+static void IDP_FreeIDPArray(IDProperty *prop, const bool do_id_user)
 {
 	int i;
 	
 	BLI_assert(prop->type == IDP_IDPARRAY);
 
 	for (i = 0; i < prop->len; i++)
-		IDP_FreeProperty(GETPROP(prop, i));
+		IDP_FreeProperty_ex(GETPROP(prop, i), do_id_user);
 
 	if (prop->data.pointer)
 		MEM_freeN(prop->data.pointer);
@@ -727,13 +727,13 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con
  * This is because all ID Property freeing functions free only direct data (not the ID Property
  * struct itself), but for Groups the child properties *are* considered
  * direct data. */
-static void IDP_FreeGroup(IDProperty *prop)
+static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
 {
 	IDProperty *loop;
 
 	BLI_assert(prop->type == IDP_GROUP);
 	for (loop = prop->data.group.first; loop; loop = loop->next) {
-		IDP_FreeProperty(loop);
+		IDP_FreeProperty_ex(loop, do_id_user);
 	}
 	BLI_freelistN(&prop->data.group);
 }
@@ -1038,7 +1038,7 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
  * \note This will free allocated data, all child properties of arrays and groups, and unlink IDs!
  * But it does not free the actual IDProperty struct itself.
  */
-void IDP_FreeProperty(IDProperty *prop)
+void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user)
 {
 	switch (prop->type) {
 		case IDP_ARRAY:
@@ -1048,17 +1048,24 @@ void IDP_FreeProperty(IDProperty *prop)
 			IDP_FreeString(prop);
 			break;
 		case IDP_GROUP:
-			IDP_FreeGroup(prop);
+			IDP_FreeGroup(prop, do_id_user);
 			break;
 		case IDP_IDPARRAY:
-			IDP_FreeIDPArray(prop);
+			IDP_FreeIDPArray(prop, do_id_user);
 			break;
 		case IDP_ID:
-			id_us_min(IDP_Id(prop));
+			if (do_id_user) {
+				id_us_min(IDP_Id(prop));
+			}
 			break;
 	}
 }
 
+void IDP_FreeProperty(IDProperty *prop)
+{
+	IDP_FreeProperty_ex(prop, true);
+}
+
 void IDP_ClearProperty(IDProperty *prop)
 {
 	IDP_FreeProperty(prop);
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index a5be5915ca5..d14e0cf0b65 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -719,10 +719,10 @@ void BKE_libblock_relink_to_newid(ID *id)
 	BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
 }
 
-void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id)
+void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id, const bool do_id_user)
 {
 	if (id->properties) {
-		IDP_FreeProperty(id->properties);
+		IDP_FreeProperty_ex(id->properties, do_id_user);
 		MEM_freeN(id->properties);
 	}
 }
@@ -747,14 +747,6 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
 	BPY_id_release(id);
 #endif
 
-	/* XXX TODO this is a no-go, have to check how to remove that call!!! */
-	/* Currently we should remap id to NULL regardless do_id_user,
-	   because when we will try to remove some other block,
-       which point to this one with idprop, the attempt
-	   to free will cause crash because of bad pointer on
-       freed id. Else we should pass do_id_user to IDP_FreeProperty */
-	libblock_remap_data(bmain, NULL, id, NULL, 0, NULL);
-
 	if (do_id_user) {
 		BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
 	}
@@ -880,7 +872,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
 
 	BLI_remlink(lb, id);
 
-	BKE_libblock_free_data(bmain, id);
+	BKE_libblock_free_data(bmain, id, do_id_user);
 	BKE_main_unlock(bmain);
 
 	MEM_freeN(id);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 3f3b4896653..f3223e31b17 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1828,7 +1828,7 @@ void ntreeFreeTree(bNodeTree *ntree)
 		if (tntree == ntree)
 			break;
 	if (tntree == NULL) {
-		BKE_libblock_free_data(G.main, &ntree->id);
+		BKE_libblock_free_data(G.main, &ntree->id, true);
 	}
 }
 
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 4351cd22b18..d0522fdd7d4 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -489,7 +489,7 @@ void wm_close_and_free_all(bContext *C, ListBase *wmlist)
 	while ((wm = wmlist->first)) {
 		wm_close_and_free(C, wm);
 		BLI_remlink(wmlist, wm);
-		BKE_libblock_free_data(bmain, &wm->id);
+		BKE_libblock_free_data(bmain, &wm->id, true);
 		MEM_freeN(wm);
 	}
 }




More information about the Bf-blender-cvs mailing list