GUI: Improve thread-safety for icons set access

The previous commit was not sufficient as getIconsSet() returns a
reference to the SearchSet and it could then be used after the
mutex had been unlocked and while it was being modified in
initIconsSet() called in another thread.
This commit is contained in:
Thierry Crozat 2022-06-29 19:27:27 +01:00 committed by Eugene Sandulenko
parent 8cda1fe870
commit b248add106
3 changed files with 10 additions and 4 deletions

View File

@ -96,10 +96,9 @@ public:
ThemeEval *xmlEval() { return _theme->getEvaluator(); }
Common::SearchSet &getIconsSet() {
Common::StackLock lock(_iconsMutex);
return _iconsSet;
}
void lockIconsSet() { _iconsMutex.lock(); }
void unlockIconsSet() { _iconsMutex.unlock(); }
Common::SearchSet &getIconsSet() { return _iconsSet; }
int16 getGUIWidth() const { return _baseWidth; }
int16 getGUIHeight() const { return _baseHeight; }

View File

@ -183,6 +183,7 @@ LauncherDialog::LauncherDialog(const Common::String &dialogName, LauncherChooser
Common::ArchiveMemberList mdFiles;
g_gui.lockIconsSet();
g_gui.getIconsSet().listMatchingMembers(mdFiles, "*.xml");
for (Common::ArchiveMemberList::iterator md = mdFiles.begin(); md != mdFiles.end(); ++md) {
if (_metadataParser.loadStream((*md)->createReadStream()) == false) {
@ -194,6 +195,7 @@ LauncherDialog::LauncherDialog(const Common::String &dialogName, LauncherChooser
}
_metadataParser.close();
}
g_gui.unlockIconsSet();
}
LauncherDialog::~LauncherDialog() {

View File

@ -291,9 +291,11 @@ Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int re
#ifdef USE_PNG
const Graphics::Surface *srcSurface = nullptr;
Image::PNGDecoder decoder;
g_gui.lockIconsSet();
if (g_gui.getIconsSet().hasFile(name)) {
Common::SeekableReadStream *stream = g_gui.getIconsSet().createReadStreamForMember(name);
if (!decoder.loadStream(*stream)) {
g_gui.unlockIconsSet();
warning("Error decoding PNG");
return surf;
}
@ -308,10 +310,12 @@ Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int re
} else {
debug(5, "GridWidget: Cannot read file '%s'", name.c_str());
}
g_gui.unlockIconsSet();
#else
error("No PNG support compiled");
#endif
} else if (name.hasSuffix(".svg")) {
g_gui.lockIconsSet();
if (g_gui.getIconsSet().hasFile(name)) {
Common::SeekableReadStream *stream = g_gui.getIconsSet().createReadStreamForMember(name);
Graphics::SVGBitmap *image = nullptr;
@ -325,6 +329,7 @@ Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int re
} else {
debug(5, "GridWidget: Cannot read file '%s'", name.c_str());
}
g_gui.unlockIconsSet();
}
return surf;
}