Fix race condition in "All" asset library building

Multiple threads may try to load the "All" asset library catalogs, so
avoid working on the same catalog service in parallel.

Found when testing #118463 on top of #118382, by creating a sculpt brush
asset while the asset shelf is open. The 3D View header would trigger
reloading of the "All" asset library catalogs to display node assets in
header pulldowns, while the asset shelf triggered a threaded reload of
the asset library.
This commit is contained in:
Julian Eisel
2024-02-19 17:55:37 +01:00
parent d0cf0f34dc
commit edcdbf1cbd

View File

@@ -18,18 +18,21 @@ AllAssetLibrary::AllAssetLibrary() : AssetLibrary(ASSET_LIBRARY_ALL) {}
void AllAssetLibrary::rebuild(const bool reload_catalogs)
{
/* Start with empty catalog storage. */
catalog_service = std::make_unique<AssetCatalogService>(AssetCatalogService::read_only_tag());
/* Start with empty catalog storage. Don't do this directly in #this.catalog_service to avoid
* race conditions. Rather build into a new service and replace the current one when done. */
std::unique_ptr<AssetCatalogService> new_catalog_service = std::make_unique<AssetCatalogService>(
AssetCatalogService::read_only_tag());
AssetLibrary::foreach_loaded(
[&](AssetLibrary &nested) {
if (reload_catalogs) {
nested.catalog_service->reload_catalogs();
}
catalog_service->add_from_existing(*nested.catalog_service);
new_catalog_service->add_from_existing(*nested.catalog_service);
},
false);
catalog_service->rebuild_tree();
new_catalog_service->rebuild_tree();
this->catalog_service = std::move(new_catalog_service);
}
void AllAssetLibrary::refresh_catalogs()