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>2019-02-18 17:17:06 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2019-02-18 17:27:29 +0300
commit2c12c9b61e5081a98b9ba40d9f8c7d9f63fc9725 (patch)
tree52d890b75eac2e6d47c1ec8b739d9fc5de41961c
parenta0d0d37ecd9f9d0b6503f89f9587ad44eeab43ca (diff)
ID management: forbid refcount of used IDs when user ID is outside of Main.
This is related to T61660, but actually does not fix that specific issue (which is even worse - outside-of-Main ID using inside-of-Main IDs... yuck).
-rw-r--r--source/blender/blenkernel/intern/library_query.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 04c393ba733..c9c223c8724 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -90,7 +90,10 @@
if (!((_data)->status & IDWALK_STOP)) { \
const int _flag = (_data)->flag; \
ID *old_id = *(id_pp); \
- const int callback_return = (_data)->callback((_data)->user_data, (_data)->self_id, id_pp, _cb_flag | (_data)->cb_flag); \
+ const int callback_return = (_data)->callback((_data)->user_data, \
+ (_data)->self_id, \
+ id_pp, \
+ (_cb_flag | (_data)->cb_flag) & ~(_data)->cb_flag_clear); \
if (_flag & IDWALK_READONLY) { \
BLI_assert(*(id_pp) == old_id); \
} \
@@ -131,6 +134,7 @@ typedef struct LibraryForeachIDData {
ID *self_id;
int flag;
int cb_flag;
+ int cb_flag_clear;
LibraryIDLinkCallback callback;
void *user_data;
int status;
@@ -369,6 +373,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
data.self_id = id;
data.cb_flag = ID_IS_LINKED(id) ? IDWALK_CB_INDIRECT_USAGE : 0;
+ /* When an ID is not in Main database, it should never refcount IDs it is using. */
+ data.cb_flag_clear = (id->tag & LIB_TAG_NO_MAIN) ? IDWALK_CB_USER | IDWALK_CB_USER_ONE : 0;
if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY)) {
/* Note that this is minor optimization, even in worst cases (like id being an object with lots of