]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Protect font initialization with mutex
authorsfan5 <sfan5@live.de>
Fri, 17 Dec 2021 22:49:47 +0000 (23:49 +0100)
committersfan5 <sfan5@live.de>
Sat, 18 Dec 2021 19:38:33 +0000 (20:38 +0100)
fixes #4532

src/client/fontengine.cpp
src/client/fontengine.h

index f64315db476a9f3355f17cc7ebd8a1ca9689b28e..35e908b0cc66f44027b7eaeea49a7d71b886fc77 100644 (file)
@@ -84,11 +84,13 @@ FontEngine::~FontEngine()
 /******************************************************************************/
 void FontEngine::cleanCache()
 {
+       RecursiveMutexAutoLock l(m_font_mutex);
+
        for (auto &font_cache_it : m_font_cache) {
 
                for (auto &font_it : font_cache_it) {
                        font_it.second->drop();
-                       font_it.second = NULL;
+                       font_it.second = nullptr;
                }
                font_cache_it.clear();
        }
@@ -122,6 +124,8 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
        if (spec.size == FONT_SIZE_UNSPECIFIED)
                spec.size = m_default_size[spec.mode];
 
+       RecursiveMutexAutoLock l(m_font_mutex);
+
        const auto &cache = m_font_cache[spec.getHash()];
        auto it = cache.find(spec.size);
        if (it != cache.end())
@@ -149,13 +153,7 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
 /******************************************************************************/
 unsigned int FontEngine::getTextHeight(const FontSpec &spec)
 {
-       irr::gui::IGUIFont *font = getFont(spec);
-
-       // use current skin font as fallback
-       if (font == NULL) {
-               font = m_env->getSkin()->getFont();
-       }
-       FATAL_ERROR_IF(font == NULL, "Could not get skin font");
+       gui::IGUIFont *font = getFont(spec);
 
        return font->getDimension(L"Some unimportant example String").Height;
 }
@@ -163,28 +161,15 @@ unsigned int FontEngine::getTextHeight(const FontSpec &spec)
 /******************************************************************************/
 unsigned int FontEngine::getTextWidth(const std::wstring &text, const FontSpec &spec)
 {
-       irr::gui::IGUIFont *font = getFont(spec);
-
-       // use current skin font as fallback
-       if (font == NULL) {
-               font = m_env->getSkin()->getFont();
-       }
-       FATAL_ERROR_IF(font == NULL, "Could not get font");
+       gui::IGUIFont *font = getFont(spec);
 
        return font->getDimension(text.c_str()).Width;
 }
 
-
 /** get line height for a specific font (including empty room between lines) */
 unsigned int FontEngine::getLineHeight(const FontSpec &spec)
 {
-       irr::gui::IGUIFont *font = getFont(spec);
-
-       // use current skin font as fallback
-       if (font == NULL) {
-               font = m_env->getSkin()->getFont();
-       }
-       FATAL_ERROR_IF(font == NULL, "Could not get font");
+       gui::IGUIFont *font = getFont(spec);
 
        return font->getDimension(L"Some unimportant example String").Height
                        + font->getKerningHeight();
@@ -238,22 +223,9 @@ void FontEngine::readSettings()
 void FontEngine::updateSkin()
 {
        gui::IGUIFont *font = getFont();
+       assert(font);
 
-       if (font)
-               m_env->getSkin()->setFont(font);
-       else
-               errorstream << "FontEngine: Default font file: " <<
-                               "\n\t\"" << g_settings->get("font_path") << "\"" <<
-                               "\n\trequired for current screen configuration was not found" <<
-                               " or was invalid file format." <<
-                               "\n\tUsing irrlicht default font." << std::endl;
-
-       // If we did fail to create a font our own make irrlicht find a default one
-       font = m_env->getSkin()->getFont();
-       FATAL_ERROR_IF(font == NULL, "Could not create/get font");
-
-       u32 text_height = font->getDimension(L"Hello, world!").Height;
-       infostream << "FontEngine: measured text_height=" << text_height << std::endl;
+       m_env->getSkin()->setFont(font);
 }
 
 /******************************************************************************/
index 3d389ea48bfa32a1f51658fd2558aecc9f8cb92f..403ac2e48680cb44dcc2a1de1f33723b3eba264e 100644 (file)
@@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #pragma once
 
 #include <map>
-#include <vector>
 #include "util/basic_macros.h"
 #include "irrlichttypes.h"
 #include <IGUIFont.h>
 #include <IGUISkin.h>
 #include <IGUIEnvironment.h>
 #include "settings.h"
+#include "threading/mutex_auto_lock.h"
 
 #define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
 
@@ -152,6 +152,9 @@ class FontEngine
        /** pointer to irrlicht gui environment */
        gui::IGUIEnvironment* m_env = nullptr;
 
+       /** mutex used to protect font init and cache */
+       std::recursive_mutex m_font_mutex;
+
        /** internal storage for caching fonts of different size */
        std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];