diff --git a/include/mbgl/util/exclusive.hpp b/include/mbgl/util/exclusive.hpp new file mode 100644 index 000000000..bb3395996 --- /dev/null +++ b/include/mbgl/util/exclusive.hpp @@ -0,0 +1,30 @@ +#ifndef MBGL_UTIL_EXCLUSIVE +#define MBGL_UTIL_EXCLUSIVE + +#include +#include + + +namespace mbgl { +namespace util { + +template +class exclusive { +public: + inline exclusive(T* val, std::unique_ptr> mtx) : ptr(val), lock(std::move(mtx)) {} + + inline T* operator->() { return ptr; } + inline const T* operator->() const { return ptr; } + inline T* operator*() { return ptr; } + inline const T* operator*() const { return ptr; } + +private: + T *ptr; + std::unique_ptr> lock; +}; + + +} // end namespace util +} // end namespace mbgl + +#endif diff --git a/src/mbgl/text/glyph_store.cpp b/src/mbgl/text/glyph_store.cpp index 031720325..4ee853b1e 100644 --- a/src/mbgl/text/glyph_store.cpp +++ b/src/mbgl/text/glyph_store.cpp @@ -20,19 +20,16 @@ namespace mbgl { void FontStack::insert(uint32_t id, const SDFGlyph &glyph) { - std::lock_guard lock(mtx); metrics.emplace(id, glyph.metrics); bitmaps.emplace(id, glyph.bitmap); sdfs.emplace(id, glyph); } const std::map &FontStack::getMetrics() const { - std::lock_guard lock(mtx); return metrics; } const std::map &FontStack::getSDFs() const { - std::lock_guard lock(mtx); return sdfs; } @@ -40,8 +37,6 @@ const Shaping FontStack::getShaping(const std::u32string &string, const float ma const float lineHeight, const float horizontalAlign, const float verticalAlign, const float justify, const float spacing, const vec2 &translate) const { - std::lock_guard lock(mtx); - Shaping shaping; int32_t x = std::round(translate.x * 24); // one em @@ -179,8 +174,6 @@ GlyphPBF::~GlyphPBF() { } void GlyphPBF::parse(FontStack &stack) { - std::lock_guard lock(mtx); - if (!data.size()) { // If there is no data, this means we either haven't received any data, or // we have already parsed the data. @@ -253,7 +246,7 @@ void GlyphStore::setURL(const std::string &url) { glyphURL = url; } -bool GlyphStore::requestGlyphRangesIfNeeded(const std::string& fontStack, +bool GlyphStore::requestGlyphRangesIfNeeded(const std::string& fontStackName, const std::set& glyphRanges) { bool requestIsNeeded = false; @@ -261,18 +254,19 @@ bool GlyphStore::requestGlyphRangesIfNeeded(const std::string& fontStack, return requestIsNeeded; } - auto callback = [this, fontStack](GlyphPBF* glyph) { - glyph->parse(*createFontStack(fontStack)); + auto callback = [this, fontStackName](GlyphPBF* glyph) { + auto fontStack = createFontStack(fontStackName); + glyph->parse(**fontStack); asyncEmitGlyphRangeLoaded->send(); }; std::lock_guard lock(rangesMutex); - auto& rangeSets = ranges[fontStack]; + auto& rangeSets = ranges[fontStackName]; for (const auto& range : glyphRanges) { const auto& rangeSets_it = rangeSets.find(range); if (rangeSets_it == rangeSets.end()) { - auto glyph = util::make_unique(glyphURL, fontStack, range, env, callback); + auto glyph = util::make_unique(glyphURL, fontStackName, range, env, callback); rangeSets.emplace(range, std::move(glyph)); requestIsNeeded = true; continue; @@ -286,15 +280,15 @@ bool GlyphStore::requestGlyphRangesIfNeeded(const std::string& fontStack, return requestIsNeeded; } -FontStack* GlyphStore::createFontStack(const std::string &fontStack) { - std::lock_guard lock(stacksMutex); +util::exclusive GlyphStore::createFontStack(const std::string &fontStack) { + auto lock = util::make_unique>(stacksMutex); auto stack_it = stacks.find(fontStack); if (stack_it == stacks.end()) { stack_it = stacks.emplace(fontStack, util::make_unique()).first; } - return stack_it->second.get(); + return { stack_it->second.get(), std::move(lock) }; } util::exclusive GlyphStore::getFontStack(const std::string &fontStack) { diff --git a/src/mbgl/text/glyph_store.hpp b/src/mbgl/text/glyph_store.hpp index a42130855..e13ed1f1d 100644 --- a/src/mbgl/text/glyph_store.hpp +++ b/src/mbgl/text/glyph_store.hpp @@ -54,7 +54,6 @@ private: std::map bitmaps; std::map metrics; std::map sdfs; - mutable std::mutex mtx; }; class GlyphPBF { @@ -82,8 +81,6 @@ private: Environment& env; Request* req = nullptr; - - mutable std::mutex mtx; }; // Manages Glyphrange PBF loading. @@ -114,7 +111,7 @@ public: private: void emitGlyphRangeLoaded(); - FontStack* createFontStack(const std::string &fontStack); + util::exclusive createFontStack(const std::string &fontStack); std::string glyphURL; Environment &env;