From f30b909909a14e07b9ba3ae81e2034726fbbd2e3 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Jul 2020 10:01:48 -0600 Subject: [PATCH] Fix a bug related to trashed keys. (cherry picked from H'uru e2b5786988a82dfe2485030aed9738bddb4171ac) It appears that the hsTArray memory management really sucks for smart pointers like plKey. The crash mentioned at http://forum.guildofwriters.org/viewtopic.php?f=117&t=6291 went away immediately after switching plKeyCollector to an std::set. --- .../Sources/Plasma/Apps/plPageInfo/plPageInfo.cpp | 12 ++++++------ .../Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp | 2 +- .../PubUtilLib/plResMgr/plRegistryHelpers.cpp | 12 +----------- .../Plasma/PubUtilLib/plResMgr/plRegistryHelpers.h | 14 +++++++++----- .../Plasma/PubUtilLib/plResMgr/plResManager.cpp | 7 +++---- .../PubUtilLib/plResMgr/plResManagerHelper.h | 3 +-- 6 files changed, 21 insertions(+), 29 deletions(-) diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plPageInfo/plPageInfo.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plPageInfo/plPageInfo.cpp index 61a84d40..27ad4d4e 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plPageInfo/plPageInfo.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plPageInfo/plPageInfo.cpp @@ -155,7 +155,7 @@ int main(int argc, char* argv[]) class plSoundBufferCollector : public plRegistryPageIterator, public plKeyCollector { public: - plSoundBufferCollector(hsTArray& keyArray) + plSoundBufferCollector(std::set& keyArray) : plKeyCollector(keyArray) {} hsBool EatPage(plRegistryPageNode* page) @@ -169,14 +169,14 @@ public: bool DumpSounds() { - hsTArray soundKeys; + std::set soundKeys; plSoundBufferCollector soundCollector(soundKeys); gResMgr->IterateAllPages(&soundCollector); - for (int i = 0; i < soundKeys.GetCount(); i++) + for (std::set::iterator it = soundKeys.begin(); it != soundKeys.end(); ++it) { - plSoundBuffer* buffer = plSoundBuffer::ConvertNoRef(soundKeys[i]->VerifyLoaded()); + plSoundBuffer* buffer = plSoundBuffer::ConvertNoRef((*it)->VerifyLoaded()); if (buffer) { // Ref it... @@ -207,7 +207,7 @@ bool DumpSounds() } } - soundKeys.Reset(); + soundKeys.clear(); plIndirectUnloadIterator iter; gResMgr->IterateAllPages(&iter); @@ -267,4 +267,4 @@ bool DumpStats(const char* patchDir) plStatDumpIterator statDump(patchDir); gResMgr->IterateAllPages(&statDump); return true; -} \ No newline at end of file +} diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp index 785dd267..4bb2b85e 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp @@ -168,7 +168,7 @@ public: if( stricmp( pageNode->GetPageInfo().GetAge(), fAgeName ) == 0 ) { // Try loading and searching thru this page - hsTArray keyRefs; + std::set keyRefs; IGetResMgr()->LoadPageKeys( pageNode ); plKeyCollector coll( keyRefs ); diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.cpp index e285f148..6194e16d 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.cpp @@ -42,18 +42,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plRegistryHelpers.h" #include "plRegistryNode.h" -plKeyCollector::plKeyCollector( hsTArray &keys ) : fKeys( keys ) -{ -} - -hsBool plKeyCollector::EatKey(const plKey& key) -{ - fKeys.Append(key); - return true; -} - hsBool plIndirectUnloadIterator::EatPage(plRegistryPageNode* page) { page->IterateKeys(this); return true; -} \ No newline at end of file +} diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.h index 8fd534c7..f7d3879a 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.h +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plRegistryHelpers.h @@ -53,8 +53,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #define _plRegistryHelpers_h #include "hsTypes.h" -#include "hsTemplates.h" #include "../pnKeyedObject/plKey.h" +#include class plKey; class plRegistryPageNode; @@ -77,15 +77,19 @@ public: //// plKeyCollector ////////////////////////////////////////////////////////// -// Helper key iterator that collects the given keys into the given hsTArray +// Helper key iterator that collects keys into an std::set class plKeyCollector : public plRegistryKeyIterator { protected: - hsTArray &fKeys; + std::set& fKeys; public: - plKeyCollector(hsTArray& keys); - virtual hsBool EatKey(const plKey& key); + plKeyCollector(std::set& keys) : fKeys(keys) { } + virtual hsBool EatKey(const plKey& key) + { + fKeys.insert(key); + return true; + } }; // If you loaded keys with another iterator, this will ensure that they're unloaded diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp index 50e66c39..92313fd9 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp @@ -1016,12 +1016,11 @@ void plResManager::SetProgressBarProc(plProgressProc proc) class plResAgeHolder : public hsRefCnt { public: - hsTArray fKeys; + std::set fKeys; std::string fAge; plResAgeHolder() {} plResAgeHolder( const char* age ) : fAge( age ) {} - ~plResAgeHolder() { fKeys.Reset(); } }; //// plResHolderIterator ///////////////////////////////////////////////////// @@ -1029,12 +1028,12 @@ class plResAgeHolder : public hsRefCnt class plResHolderIterator : public plRegistryPageIterator { protected: - hsTArray& fKeys; + std::set& fKeys; const char* fAgeName; plResManager* fResMgr; public: - plResHolderIterator(const char* age, hsTArray& keys, plResManager* resMgr) + plResHolderIterator(const char* age, std::set& keys, plResManager* resMgr) : fAgeName(age), fKeys(keys), fResMgr(resMgr) {} virtual hsBool EatPage(plRegistryPageNode* page) diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManagerHelper.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManagerHelper.h index ed6ab412..07e04535 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManagerHelper.h +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManagerHelper.h @@ -135,12 +135,11 @@ class plResPageKeyRefList : public plKeyCollector { protected: - hsTArray fKeyList; + std::set fKeyList; public: plResPageKeyRefList() : plKeyCollector( fKeyList ) {} - virtual ~plResPageKeyRefList() { fKeyList.Reset(); } }; #endif // _plResManagerHelper_h