Skip to content

Commit 49f7d24

Browse files
committedDec 18, 2021
Protect font initialization with mutex
fixes #4532
1 parent b2409b1 commit 49f7d24

File tree

2 files changed

+14
-39
lines changed

2 files changed

+14
-39
lines changed
 

Diff for: ‎src/client/fontengine.cpp

+10-38
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,13 @@ FontEngine::~FontEngine()
8484
/******************************************************************************/
8585
void FontEngine::cleanCache()
8686
{
87+
RecursiveMutexAutoLock l(m_font_mutex);
88+
8789
for (auto &font_cache_it : m_font_cache) {
8890

8991
for (auto &font_it : font_cache_it) {
9092
font_it.second->drop();
91-
font_it.second = NULL;
93+
font_it.second = nullptr;
9294
}
9395
font_cache_it.clear();
9496
}
@@ -122,6 +124,8 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
122124
if (spec.size == FONT_SIZE_UNSPECIFIED)
123125
spec.size = m_default_size[spec.mode];
124126

127+
RecursiveMutexAutoLock l(m_font_mutex);
128+
125129
const auto &cache = m_font_cache[spec.getHash()];
126130
auto it = cache.find(spec.size);
127131
if (it != cache.end())
@@ -149,42 +153,23 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
149153
/******************************************************************************/
150154
unsigned int FontEngine::getTextHeight(const FontSpec &spec)
151155
{
152-
irr::gui::IGUIFont *font = getFont(spec);
153-
154-
// use current skin font as fallback
155-
if (font == NULL) {
156-
font = m_env->getSkin()->getFont();
157-
}
158-
FATAL_ERROR_IF(font == NULL, "Could not get skin font");
156+
gui::IGUIFont *font = getFont(spec);
159157

160158
return font->getDimension(L"Some unimportant example String").Height;
161159
}
162160

163161
/******************************************************************************/
164162
unsigned int FontEngine::getTextWidth(const std::wstring &text, const FontSpec &spec)
165163
{
166-
irr::gui::IGUIFont *font = getFont(spec);
167-
168-
// use current skin font as fallback
169-
if (font == NULL) {
170-
font = m_env->getSkin()->getFont();
171-
}
172-
FATAL_ERROR_IF(font == NULL, "Could not get font");
164+
gui::IGUIFont *font = getFont(spec);
173165

174166
return font->getDimension(text.c_str()).Width;
175167
}
176168

177-
178169
/** get line height for a specific font (including empty room between lines) */
179170
unsigned int FontEngine::getLineHeight(const FontSpec &spec)
180171
{
181-
irr::gui::IGUIFont *font = getFont(spec);
182-
183-
// use current skin font as fallback
184-
if (font == NULL) {
185-
font = m_env->getSkin()->getFont();
186-
}
187-
FATAL_ERROR_IF(font == NULL, "Could not get font");
172+
gui::IGUIFont *font = getFont(spec);
188173

189174
return font->getDimension(L"Some unimportant example String").Height
190175
+ font->getKerningHeight();
@@ -238,22 +223,9 @@ void FontEngine::readSettings()
238223
void FontEngine::updateSkin()
239224
{
240225
gui::IGUIFont *font = getFont();
226+
assert(font);
241227

242-
if (font)
243-
m_env->getSkin()->setFont(font);
244-
else
245-
errorstream << "FontEngine: Default font file: " <<
246-
"\n\t\"" << g_settings->get("font_path") << "\"" <<
247-
"\n\trequired for current screen configuration was not found" <<
248-
" or was invalid file format." <<
249-
"\n\tUsing irrlicht default font." << std::endl;
250-
251-
// If we did fail to create a font our own make irrlicht find a default one
252-
font = m_env->getSkin()->getFont();
253-
FATAL_ERROR_IF(font == NULL, "Could not create/get font");
254-
255-
u32 text_height = font->getDimension(L"Hello, world!").Height;
256-
infostream << "FontEngine: measured text_height=" << text_height << std::endl;
228+
m_env->getSkin()->setFont(font);
257229
}
258230

259231
/******************************************************************************/

Diff for: ‎src/client/fontengine.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2020
#pragma once
2121

2222
#include <map>
23-
#include <vector>
2423
#include "util/basic_macros.h"
2524
#include "irrlichttypes.h"
2625
#include <IGUIFont.h>
2726
#include <IGUISkin.h>
2827
#include <IGUIEnvironment.h>
2928
#include "settings.h"
29+
#include "threading/mutex_auto_lock.h"
3030

3131
#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
3232

@@ -152,6 +152,9 @@ class FontEngine
152152
/** pointer to irrlicht gui environment */
153153
gui::IGUIEnvironment* m_env = nullptr;
154154

155+
/** mutex used to protect font init and cache */
156+
std::recursive_mutex m_font_mutex;
157+
155158
/** internal storage for caching fonts of different size */
156159
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];
157160

0 commit comments

Comments
 (0)
Please sign in to comment.