[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