[Bf-blender-cvs] [46171727409] master: Fix race condition when loading multiple File/Asset Browsers at once

Julian Eisel noreply at git.blender.org
Thu Jul 1 15:23:25 CEST 2021


Commit: 461717274091113112416d2733d4b44eacb57017
Author: Julian Eisel
Date:   Thu Jul 1 15:09:08 2021 +0200
Branches: master
https://developer.blender.org/rB461717274091113112416d2733d4b44eacb57017

Fix race condition when loading multiple File/Asset Browsers at once

When multiple File or Asset Browsers would load at once (e.g. when loading a
file with two File Browsers open) and they would load multiple directories or
.blend files (using the Recursions option in the File Browser or loading an
asset library with multiple .blends), often only one File/Asset Browser would
correctly load all files. Others would be incomplete or entirely empty. That
was because of a race condition, where the directories or .blend files would be
loaded concurrently and the first one that finished would cancel the other
ones. This again happened because they used the job system with the same
"owner", which by design makes all jobs with the same owner cancel as soon as
the first is finished.
Address this by making sure they have different owners. That is, not the scene
anymore, but the filelist the job belongs to. Doesn't make much sense to use
the scene as owner for scene-unrelated file loading anyway.

Steps to reproduce were:
* Open two File Browsers as regular editors.
* In the Display Settings popover, set "Recursions" to 2 or 3 levels.
* Navigate to a directory with plenty of subdirectories in both File Browsers.
* Save the file.
* Reload the file, one of the File Browsers likely has an incomplete file list.

Alternatively, use Asset Browsers and open an asset library containing multiple
.blends.

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

M	source/blender/editors/include/ED_fileselect.h
M	source/blender/editors/space_file/file_draw.c
M	source/blender/editors/space_file/file_ops.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/editors/space_file/filesel.c
M	source/blender/editors/space_file/space_file.c
M	source/blender/makesrna/intern/rna_space.c

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

diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 8118e3c6c69..cff3a8dfa5f 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -136,13 +136,9 @@ void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y);
 
 void ED_operatormacros_file(void);
 
-void ED_fileselect_clear(struct wmWindowManager *wm,
-                         struct Scene *owner_scene,
-                         struct SpaceFile *sfile);
+void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile);
 
-void ED_fileselect_exit(struct wmWindowManager *wm,
-                        struct Scene *owner_scene,
-                        struct SpaceFile *sfile);
+void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile);
 
 bool ED_fileselect_is_asset_browser(const struct SpaceFile *sfile);
 struct ID *ED_fileselect_active_asset_get(const struct SpaceFile *sfile);
@@ -166,7 +162,7 @@ int ED_file_icon(const struct FileDirEntry *file);
 
 void ED_file_read_bookmarks(void);
 
-void ED_file_change_dir_ex(struct bContext *C, struct bScreen *screen, struct ScrArea *area);
+void ED_file_change_dir_ex(struct bContext *C, struct ScrArea *area);
 void ED_file_change_dir(struct bContext *C);
 
 void ED_file_path_button(struct bScreen *screen,
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index d947d361fdf..29cac294eaf 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -552,7 +552,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
       }
 
       /* to make sure we show what is on disk */
-      ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+      ED_fileselect_clear(wm, sfile);
     }
 
     ED_region_tag_redraw(region);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 0584e2ff938..1ba1c1d6954 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1882,7 +1882,7 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
   SpaceFile *sfile = CTX_wm_space_file(C);
   struct FSMenu *fsmenu = ED_fsmenu_get();
 
-  ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+  ED_fileselect_clear(wm, sfile);
 
   /* refresh system directory menu */
   fsmenu_refresh_system_category(fsmenu);
@@ -2360,7 +2360,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
   sfile->scroll_offset = 0;
 
   /* reload dir to make sure we're seeing what's in the directory */
-  ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+  ED_fileselect_clear(wm, sfile);
 
   if (do_diropen) {
     BLI_strncpy(params->dir, path, sizeof(params->dir));
@@ -2611,7 +2611,7 @@ static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
 
   if (params) {
     params->flag ^= FILE_HIDE_DOT;
-    ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+    ED_fileselect_clear(wm, sfile);
     WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
   }
 
@@ -2908,7 +2908,7 @@ static int file_delete_exec(bContext *C, wmOperator *op)
     }
   }
 
-  ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+  ED_fileselect_clear(wm, sfile);
   WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
 
   return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 40a7be0423e..5208a6f426f 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -3505,7 +3505,7 @@ void filelist_readjob_start(FileList *filelist, const bContext *C)
   /* setup job */
   wm_job = WM_jobs_get(CTX_wm_manager(C),
                        CTX_wm_window(C),
-                       CTX_data_scene(C),
+                       filelist,
                        "Listing Dirs...",
                        WM_JOB_PROGRESS,
                        WM_JOB_TYPE_FILESEL_READDIR);
@@ -3521,12 +3521,12 @@ void filelist_readjob_start(FileList *filelist, const bContext *C)
   WM_jobs_start(CTX_wm_manager(C), wm_job);
 }
 
-void filelist_readjob_stop(wmWindowManager *wm, Scene *owner_scene)
+void filelist_readjob_stop(FileList *filelist, wmWindowManager *wm)
 {
-  WM_jobs_kill_type(wm, owner_scene, WM_JOB_TYPE_FILESEL_READDIR);
+  WM_jobs_kill_type(wm, filelist, WM_JOB_TYPE_FILESEL_READDIR);
 }
 
-int filelist_readjob_running(wmWindowManager *wm, Scene *owner_scene)
+int filelist_readjob_running(FileList *filelist, wmWindowManager *wm)
 {
-  return WM_jobs_test(wm, owner_scene, WM_JOB_TYPE_FILESEL_READDIR);
+  return WM_jobs_test(wm, filelist, WM_JOB_TYPE_FILESEL_READDIR);
 }
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 9eb70dd8437..8617e0fb599 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -141,8 +141,8 @@ bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group);
 void filelist_freelib(struct FileList *filelist);
 
 void filelist_readjob_start(struct FileList *filelist, const struct bContext *C);
-void filelist_readjob_stop(struct wmWindowManager *wm, struct Scene *owner_scene);
-int filelist_readjob_running(struct wmWindowManager *wm, struct Scene *owner_scene);
+void filelist_readjob_stop(struct FileList *filelist, struct wmWindowManager *wm);
+int filelist_readjob_running(struct FileList *filelist, struct wmWindowManager *wm);
 
 bool filelist_cache_previews_update(struct FileList *filelist);
 void filelist_cache_previews_set(struct FileList *filelist, const bool use_previews);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 8e3fc36aa71..aec42701f12 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -1047,7 +1047,7 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *region)
  * Support updating the directory even when this isn't the active space
  * needed so RNA properties update function isn't context sensitive, see T70255.
  */
-void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
+void ED_file_change_dir_ex(bContext *C, ScrArea *area)
 {
   /* May happen when manipulating non-active spaces. */
   if (UNLIKELY(area->spacetype != SPACE_FILE)) {
@@ -1057,10 +1057,7 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
   FileSelectParams *params = ED_fileselect_get_active_params(sfile);
   if (params) {
     wmWindowManager *wm = CTX_wm_manager(C);
-    Scene *scene = WM_windows_scene_get_from_screen(wm, screen);
-    if (LIKELY(scene != NULL)) {
-      ED_fileselect_clear(wm, scene, sfile);
-    }
+    ED_fileselect_clear(wm, sfile);
 
     /* Clear search string, it is very rare to want to keep that filter while changing dir,
      * and usually very annoying to keep it actually! */
@@ -1085,9 +1082,8 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
 
 void ED_file_change_dir(bContext *C)
 {
-  bScreen *screen = CTX_wm_screen(C);
   ScrArea *area = CTX_wm_area(C);
-  ED_file_change_dir_ex(C, screen, area);
+  ED_file_change_dir_ex(C, area);
 }
 
 int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
@@ -1183,11 +1179,11 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
   return match;
 }
 
-void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
+void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile)
 {
   /* only NULL in rare cases - T29734. */
   if (sfile->files) {
-    filelist_readjob_stop(wm, owner_scene);
+    filelist_readjob_stop(sfile->files, wm);
     filelist_freelib(sfile->files);
     filelist_clear(sfile->files);
   }
@@ -1197,7 +1193,7 @@ void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfi
   WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL);
 }
 
-void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
+void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile)
 {
   if (!sfile) {
     return;
@@ -1224,7 +1220,7 @@ void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfil
   folder_history_list_free(sfile);
 
   if (sfile->files) {
-    ED_fileselect_clear(wm, owner_scene, sfile);
+    ED_fileselect_clear(wm, sfile);
     filelist_free(sfile->files);
     MEM_freeN(sfile->files);
     sfile->files = NULL;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 0418bb87768..717d28f93dc 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -206,7 +206,7 @@ static void file_exit(wmWindowManager *wm, ScrArea *area)
     sfile->previews_timer = NULL;
   }
 
-  ED_fileselect_exit(wm, NULL, sfile);
+  ED_fileselect_exit(wm, sfile);
 }
 
 static SpaceLink *file_duplicate(SpaceLink *sl)
@@ -360,7 +360,7 @@ static void file_refresh(const bContext *C, ScrArea *area)
   sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir);
 
   if (filelist_needs_force_reset(sfile->files)) {
-    filelist_readjob_stop(wm, CTX_data_scene(C));
+    filelist_readjob_stop(sfile->files, wm);
     filelist_clear(sfile->files);
   }
 
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index d0a7e4aeea3..c8a779f890d 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2980,7 +2980,7 @@ static void rna_FileBrowser_FSMenu_active_range(PointerRNA *UNUSED(ptr),
 static void rna_FileBrowser_FSMenu_active_update(struct bContext *C, PointerRNA *ptr)
 {
   ScrArea *area = rna_area_from_space(ptr);
-  ED_file_change_dir_ex(C, (bScreen *)ptr->owner_id, area);
+  ED_file_change_dir_ex(C, area);
 }
 
 static int rna_FileBrowser_FSMenuSystem_active_get(PointerRNA *ptr)



More information about the Bf-blender-cvs mailing list