-
Notifications
You must be signed in to change notification settings - Fork 3
35 bug getasset returns copy of asset ident not pointer #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
50fdd27
e2f1f9d
60cabb2
1a81fdd
79435be
c87c4c0
bf598ca
8a97620
c5eb7b4
8b2f902
7af7acf
bf6488c
81122a7
d775dab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -64,9 +64,9 @@ PinningFileHandler::PinningFileHandler(const std::string &pinningFilePath, | |||||||
| * @param resolveKey UsdAssetIdent | ||||||||
| * @return populated AssetIdentifier if key was found in pinning file. Empty AssetIdentifier if key was not found | ||||||||
| */ | ||||||||
| AssetIdentifier | ||||||||
| AssetIdentifier* | ||||||||
| PinningFileHandler::getAssetData(const std::string &resolveKey) { | ||||||||
| AssetIdentifier assetEntry; | ||||||||
| AssetIdentifier* assetEntry = nullptr; | ||||||||
|
|
||||||||
| std::string pinnedAssetPath; | ||||||||
| try { | ||||||||
|
|
@@ -76,9 +76,11 @@ PinningFileHandler::getAssetData(const std::string &resolveKey) { | |||||||
| return assetEntry; | ||||||||
| } | ||||||||
|
|
||||||||
| assetEntry = new AssetIdentifier(); | ||||||||
|
|
||||||||
| if (!pinnedAssetPath.empty()) { | ||||||||
| assetEntry.setAssetIdentifier(resolveKey); | ||||||||
| assetEntry.setResolvedAssetPath(pinnedAssetPath); | ||||||||
| assetEntry->setAssetIdentifier(resolveKey); | ||||||||
| assetEntry->setResolvedAssetPath(pinnedAssetPath); | ||||||||
| } | ||||||||
|
|
||||||||
| return assetEntry; | ||||||||
|
|
@@ -163,32 +165,31 @@ ResolverContextCache::migratePreCacheIntoAyonCache() { | |||||||
| m_PreCache.clear(); | ||||||||
| }; | ||||||||
|
|
||||||||
| AssetIdentifier | ||||||||
| AssetIdentifier* | ||||||||
| ResolverContextCache::getAsset(const std::string &assetIdentifier, | ||||||||
| const CacheName selectedCache, | ||||||||
| const bool isAyonPath) { | ||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT).Msg("ResolverContextCache::getAsset: (%s) \n", assetIdentifier.c_str()); | ||||||||
|
|
||||||||
| AssetIdentifier asset; | ||||||||
|
|
||||||||
| if (assetIdentifier.empty()) { | ||||||||
| return asset; | ||||||||
| return new AssetIdentifier(); | ||||||||
| } | ||||||||
| if (m_staticCache) { | ||||||||
| return m_pinningFileHandler->getAssetData(assetIdentifier); | ||||||||
| } | ||||||||
|
Comment on lines
174
to
179
|
||||||||
|
|
||||||||
| std::unordered_set<AssetIdentifier, AssetIdentifierHash>::iterator hit; | ||||||||
|
|
||||||||
| AssetIdentifier* asset = nullptr; | ||||||||
|
|
||||||||
| std::shared_lock<std::shared_mutex> preCacheSharedLock(m_PreCacheSharedMutex); | ||||||||
| hit = m_PreCache.find(assetIdentifier); | ||||||||
| if (hit != m_PreCache.end()) { | ||||||||
| asset = *hit; | ||||||||
| asset = const_cast<AssetIdentifier*>(&(*hit)); // get the pointer without making a copy of the object | ||||||||
| preCacheSharedLock.unlock(); | ||||||||
|
|
||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT) | ||||||||
| .Msg("ResolverContextCache::getAsset: PreCache Hit on (%s) with (%s) \n", | ||||||||
| asset.getAssetIdentifier().c_str(), asset.getResolvedAssetPath().GetPathString().c_str()); | ||||||||
| asset->getAssetIdentifier().c_str(), asset->getResolvedAssetPath().GetPathString().c_str()); | ||||||||
| return asset; | ||||||||
|
Comment on lines
184
to
193
|
||||||||
| } | ||||||||
| preCacheSharedLock.unlock(); | ||||||||
|
|
@@ -199,7 +200,7 @@ ResolverContextCache::getAsset(const std::string &assetIdentifier, | |||||||
| std::shared_lock<std::shared_mutex> ayonCacheSharedLock(m_AyonCacheSharedMutex); | ||||||||
| hit = m_AyonCache.find(assetIdentifier); | ||||||||
| if (hit != m_AyonCache.end()) { | ||||||||
| asset = *hit; | ||||||||
| asset = const_cast<AssetIdentifier*>(&(*hit)); // get the pointer without making a copy of the object | ||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT).Msg("ResolverContextCache::getAsset: AyonCache Hit \n"); | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -212,7 +213,7 @@ ResolverContextCache::getAsset(const std::string &assetIdentifier, | |||||||
| std::shared_lock<std::shared_mutex> CommonCacheSharedLock(m_CommonCacheSharedMutex); | ||||||||
| hit = m_CommonCache.find(assetIdentifier); | ||||||||
| if (hit != m_CommonCache.end()) { | ||||||||
| asset = *hit; | ||||||||
| asset = const_cast<AssetIdentifier*>(&(*hit)); // get the pointer without making a copy of the object | ||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT) | ||||||||
| .Msg("ResolverContextCache::getAsset: CommonCache Hit \n"); | ||||||||
| } | ||||||||
|
|
@@ -221,38 +222,39 @@ ResolverContextCache::getAsset(const std::string &assetIdentifier, | |||||||
| break; | ||||||||
| } | ||||||||
| } | ||||||||
| if (!asset.isEmpty()) { | ||||||||
| if (asset != nullptr) { | ||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT) | ||||||||
| .Msg("ResolverContextCache::getAsset: Cache Hit with (%s) with (%s) \n", asset.getAssetIdentifier().c_str(), | ||||||||
| asset.getResolvedAssetPath().GetPathString().c_str()); | ||||||||
| .Msg("ResolverContextCache::getAsset: Cache Hit with (%s) with (%s) \n", asset->getAssetIdentifier().c_str(), | ||||||||
| asset->getResolvedAssetPath().GetPathString().c_str()); | ||||||||
| return asset; | ||||||||
| } | ||||||||
|
|
||||||||
| asset = new AssetIdentifier(); | ||||||||
|
|
||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT).Msg("ResolverContextCache::getAsset: No Cache Hit \n"); | ||||||||
| if (isAyonPath) { | ||||||||
| std::pair<std::string, std::string> resolvedAsset = m_ayon->get()->resolvePath(assetIdentifier); | ||||||||
|
|
||||||||
| asset.setAssetIdentifier(std::move(resolvedAsset.first)); | ||||||||
| asset.setResolvedAssetPath(std::move(resolvedAsset.second)); | ||||||||
| asset->setAssetIdentifier(std::move(resolvedAsset.first)); | ||||||||
| asset->setResolvedAssetPath(std::move(resolvedAsset.second)); | ||||||||
|
|
||||||||
| TF_DEBUG(AYONUSDRESOLVER_RESOLVER_CONTEXT).Msg("ResolverContextCache::getAsset: called ayon.resolvePath() \n"); | ||||||||
| this->insert(asset); | ||||||||
| this->insert(*asset); | ||||||||
|
||||||||
| this->insert(*asset); | |
| AssetIdentifier cachedAsset(*asset); | |
| this->insert(cachedAsset); |
Copilot
AI
Apr 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This inserts into m_CommonCache while holding only a std::shared_lock on m_CommonCacheSharedMutex. unordered_set::insert is a write operation and requires exclusive locking; doing it under a shared lock is a data race in multi-threaded use. Switch this to std::unique_lock (or reuse existing write-locking patterns used elsewhere in this file).
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,7 @@ class PinningFileHandler { | |
| const std::unordered_map<std::string, std::string> &rootReplaceData); | ||
| ~PinningFileHandler() = default; | ||
|
|
||
| AssetIdentifier getAssetData(const std::string &resolveKey); | ||
| AssetIdentifier* getAssetData(const std::string &resolveKey); | ||
|
|
||
| private: | ||
| std::filesystem::path m_pinningFilePath; | ||
|
|
@@ -62,7 +62,7 @@ class ResolverContextCache { | |
| * @param isAyonPath Whether this is an AYON URI | ||
| * @return AssetIdentifier with resolved path | ||
| */ | ||
| AssetIdentifier getAsset(const std::string &assetIdentifier, const CacheName selectedCache, const bool isAyonPath); | ||
| AssetIdentifier* getAsset(const std::string &assetIdentifier, const CacheName selectedCache, const bool isAyonPath); | ||
|
|
||
|
Comment on lines
63
to
66
|
||
| /** | ||
| * @brief Set up the cache from a pinning file | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -151,7 +151,7 @@ AyonUsdResolver::_Resolve(const std::string &assetPath) const { | |
| continue; | ||
| } | ||
|
|
||
| AssetIdentifier asset; | ||
| AssetIdentifier* asset = nullptr; | ||
| std::string cleanAssetPath = *pathToResolve; | ||
| RES_FUNCS_REMOVE_SDF_ARGS(cleanAssetPath); | ||
| asset = resolverCache->getAsset(cleanAssetPath, CacheName::AYONCACHE, true); | ||
|
|
@@ -161,7 +161,7 @@ AyonUsdResolver::_Resolve(const std::string &assetPath) const { | |
| if (pos != std::string::npos) { | ||
| sdfArgs = pathToResolve->substr(pos + cleanAssetPath.length()); | ||
| } | ||
| std::string resolvedPathStr = asset.getResolvedAssetPath().GetPathString() + sdfArgs; | ||
| std::string resolvedPathStr = asset->getResolvedAssetPath().GetPathString() + sdfArgs; | ||
| ArResolvedPath resolvedPath(resolvedPathStr); | ||
|
Comment on lines
154
to
165
|
||
|
|
||
| if (resolvedPath) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function now returns a raw pointer allocated with
new AssetIdentifier()but there is no corresponding ownership contract or delete, so every successful lookup leaks. Also, when the key is missing you returnnullptr, which forces all callers to handle null (andresolver.cppcurrently doesn't). Prefer returning by value /std::optional<AssetIdentifier>/std::unique_ptr<AssetIdentifier>(with clear ownership), or return aconst AssetIdentifier&/pointer to stable storage managed by the handler.