Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-10-04 16:03:34 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-10-04 16:05:56 +0300
commite5c32844678e292a084d6d97eb2d4ba6affc217d (patch)
treedfda25a8bdab1461bc72d40f9cdcd16f7d8d4444
parentb4f9766ed13b00fbcdbd7c6e051f993caa95828c (diff)
Fix T49553: Blender 2.78 crashes when File->Data Previews ->Refresh Datablock Previews
New recursive iteration over IDs in BKE_library_foreach_ID_link() was broken by the infamous nodetree case. We cannot really recusively call this function in that case, so better to deffer handling of non-datablock NodeTrees as if real IDs here. Also fixed initial ID not being stored as handled, in rare cases this could also lead to infinite looping. To be backported to 2.78a.
-rw-r--r--source/blender/blenkernel/intern/library_query.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 718950624e2..85ddd4dcbb3 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -264,6 +264,21 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
FOREACH_FINALIZE_VOID;
}
+static void library_foreach_ID_as_subdata_link(
+ ID *id, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data)
+{
+ if (flag & IDWALK_RECURSE) {
+ /* Defer handling into main loop, recursively calling BKE_library_foreach_ID_link in IDWALK_RECURSE case is
+ * troublesome, see T49553. */
+ if (!BLI_gset_haskey(data->ids_handled, id)) {
+ BLI_gset_add(data->ids_handled, id);
+ BLI_LINKSTACK_PUSH(data->ids_todo, id);
+ }
+ }
+ else {
+ BKE_library_foreach_ID_link(id, callback, user_data, flag);
+ }
+}
/**
* Loop over all of the ID's this datablock links to.
@@ -281,6 +296,8 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
data.ids_handled = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
BLI_LINKSTACK_INIT(data.ids_todo);
+
+ BLI_gset_add(data.ids_handled, id);
}
else {
data.ids_handled = NULL;
@@ -325,7 +342,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
CALLBACK_INVOKE(scene->clip, IDWALK_USER);
if (scene->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_link((ID *)scene->nodetree, callback, user_data, flag);
+ library_foreach_ID_as_subdata_link((ID *)scene->nodetree, callback, user_data, flag, &data);
}
/* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later,
* since basact is just a pointer to one of those items. */
@@ -589,7 +606,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (material->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_link((ID *)material->nodetree, callback, user_data, flag);
+ library_foreach_ID_as_subdata_link((ID *)material->nodetree, callback, user_data, flag, &data);
}
CALLBACK_INVOKE(material->group, IDWALK_USER);
break;
@@ -600,7 +617,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
Tex *texture = (Tex *) id;
if (texture->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_link((ID *)texture->nodetree, callback, user_data, flag);
+ library_foreach_ID_as_subdata_link((ID *)texture->nodetree, callback, user_data, flag, &data);
}
CALLBACK_INVOKE(texture->ima, IDWALK_USER);
if (texture->env) {
@@ -633,7 +650,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (lamp->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_link((ID *)lamp->nodetree, callback, user_data, flag);
+ library_foreach_ID_as_subdata_link((ID *)lamp->nodetree, callback, user_data, flag, &data);
}
break;
}
@@ -673,7 +690,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (world->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_link((ID *)world->nodetree, callback, user_data, flag);
+ library_foreach_ID_as_subdata_link((ID *)world->nodetree, callback, user_data, flag, &data);
}
break;
}
@@ -817,7 +834,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
if (linestyle->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_link((ID *)linestyle->nodetree, callback, user_data, flag);
+ library_foreach_ID_as_subdata_link((ID *)linestyle->nodetree, callback, user_data, flag, &data);
}
for (lsm = linestyle->color_modifiers.first; lsm; lsm = lsm->next) {