[Bf-blender-cvs] [51c1c1cd938] master: Fix potential early-return in WM foreach_id process.

Bastien Montagne noreply at git.blender.org
Fri Oct 29 11:35:46 CEST 2021


Commit: 51c1c1cd938f990333b09d89fb063bb28864b302
Author: Bastien Montagne
Date:   Tue Oct 26 17:23:38 2021 +0200
Branches: master
https://developer.blender.org/rB51c1c1cd938f990333b09d89fb063bb28864b302

Fix potential early-return in WM foreach_id process.

Add a function to check if iteration over ID usages should stop (using
internal `IDWALK_STOP` status flag).

Use it in `BKE_LIB_FOREACHID_PROCESS_` macros, and in
`window_manager_foreach_id` to handle properly the active workspace case
(previous code could skip the call to `BKE_workspace_active_set` in case
iteration over ID usages was stopped by callback on that specific ID
usage).

Part of T90922: Fix return policy inconsistency in `scene_foreach_id`.

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

M	source/blender/blenkernel/BKE_lib_query.h
M	source/blender/blenkernel/intern/lib_query.c
M	source/blender/windowmanager/intern/wm.c

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

diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index 957a623577e..093d3fb12a6 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -143,6 +143,7 @@ enum {
 
 typedef struct LibraryForeachIDData LibraryForeachIDData;
 
+bool BKE_lib_query_foreachid_iter_stop(struct LibraryForeachIDData *data);
 bool BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
                                      struct ID **id_pp,
                                      int cb_flag);
@@ -154,7 +155,8 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
 #define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag) \
   { \
     CHECK_TYPE_ANY((_id), ID *, void *); \
-    if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag))) { \
+    BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag)); \
+    if (BKE_lib_query_foreachid_iter_stop((_data))) { \
       return; \
     } \
   } \
@@ -163,7 +165,8 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
 #define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
   { \
     CHECK_TYPE(&((_id_super)->id), ID *); \
-    if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \
+    BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag)); \
+    if (BKE_lib_query_foreachid_iter_stop((_data))) { \
       return; \
     } \
   } \
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 317621e1149..79b093bedbe 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -76,6 +76,13 @@ typedef struct LibraryForeachIDData {
   BLI_LINKSTACK_DECLARE(ids_todo, ID *);
 } LibraryForeachIDData;
 
+/** Check whether current iteration over ID usages should be stopped or not.
+ * \return true if the iteration should be stopped, false otherwise. */
+bool BKE_lib_query_foreachid_iter_stop(LibraryForeachIDData *data)
+{
+  return (data->status & IDWALK_STOP) != 0;
+}
+
 bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
 {
   if (!(data->status & IDWALK_STOP)) {
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 4458b386ab6..aa439f619be 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -91,10 +91,14 @@ static void window_manager_foreach_id(ID *id, LibraryForeachIDData *data)
     /* This pointer can be NULL during old files reading, better be safe than sorry. */
     if (win->workspace_hook != NULL) {
       ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
-      BKE_LIB_FOREACHID_PROCESS_ID(data, workspace, IDWALK_CB_NOP);
+      BKE_lib_query_foreachid_process(data, &workspace, IDWALK_CB_USER);
       /* Allow callback to set a different workspace. */
       BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
+      if (BKE_lib_query_foreachid_iter_stop(data)) {
+        return;
+      }
     }
+
     if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
       LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
         BKE_screen_foreach_id_screen_area(data, area);



More information about the Bf-blender-cvs mailing list