From f4c83a94118fd2990bf84f1ee1d9b95e717ff577 Mon Sep 17 00:00:00 2001 From: jules Date: Sat, 5 Apr 2014 17:39:31 +0100 Subject: [PATCH] Fix for a very obscure race-condition involving font string initialisation. --- modules/juce_graphics/fonts/juce_Font.cpp | 46 +++++++++++-------- .../native/juce_RenderingHelpers.h | 11 +++-- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/modules/juce_graphics/fonts/juce_Font.cpp b/modules/juce_graphics/fonts/juce_Font.cpp index 7ab54495be..bc3f850e7b 100644 --- a/modules/juce_graphics/fonts/juce_Font.cpp +++ b/modules/juce_graphics/fonts/juce_Font.cpp @@ -317,29 +317,37 @@ void Font::checkTypefaceSuitability() } //============================================================================== -const String& Font::getDefaultSansSerifFontName() +struct FontPlaceholderNames { - static const String name (""); - return name; + FontPlaceholderNames() + : sans (""), + serif (""), + mono (""), + regular ("") + { + } + + String sans, serif, mono, regular; +}; + +const FontPlaceholderNames& getFontPlaceholderNames() +{ + static FontPlaceholderNames names; + return names; } -const String& Font::getDefaultSerifFontName() -{ - static const String name (""); - return name; -} +#if JUCE_MSVC +// This is a workaround for the lack of thread-safety in MSVC's handling of function-local +// statics - if multiple threads all try to create the first Font object at the same time, +// it can cause a race-condition in creating these placeholder strings. +struct FontNamePreloader { FontNamePreloader() { getFontPlaceholderNames(); } }; +static FontNamePreloader fnp; +#endif -const String& Font::getDefaultMonospacedFontName() -{ - static const String name (""); - return name; -} - -const String& Font::getDefaultStyle() -{ - static const String style (""); - return style; -} +const String& Font::getDefaultSansSerifFontName() { return getFontPlaceholderNames().sans; } +const String& Font::getDefaultSerifFontName() { return getFontPlaceholderNames().serif; } +const String& Font::getDefaultMonospacedFontName() { return getFontPlaceholderNames().mono; } +const String& Font::getDefaultStyle() { return getFontPlaceholderNames().regular; } const String& Font::getTypefaceName() const noexcept { return font->typefaceName; } const String& Font::getTypefaceStyle() const noexcept { return font->typefaceStyle; } diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index f15734af81..01fa812fd0 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -225,10 +225,13 @@ private: hits.set (0); misses.set (0); - return glyphs.getLast(); } - return findLeastRecentlyUsedGlyph(); + if (CachedGlyphType* g = findLeastRecentlyUsedGlyph()) + return g; + + addNewGlyphSlots (32); + return glyphs.getLast(); } void addNewGlyphSlots (int num) @@ -241,8 +244,8 @@ private: CachedGlyphType* findLeastRecentlyUsedGlyph() const noexcept { - CachedGlyphType* oldest = glyphs.getLast(); - int oldestCounter = oldest->lastAccessCount; + CachedGlyphType* oldest = nullptr; + int oldestCounter = std::numeric_limits::max(); for (int i = glyphs.size() - 1; --i >= 0;) {