diff options
-rw-r--r-- | libs/minikin/LocaleListCache.cpp | 47 | ||||
-rw-r--r-- | libs/minikin/LocaleListCache.h | 23 |
2 files changed, 37 insertions, 33 deletions
diff --git a/libs/minikin/LocaleListCache.cpp b/libs/minikin/LocaleListCache.cpp index 625b4d2..c191ea6 100644 --- a/libs/minikin/LocaleListCache.cpp +++ b/libs/minikin/LocaleListCache.cpp @@ -103,46 +103,35 @@ static std::vector<Locale> parseLocaleList(const std::string& input) { return result; } -// static -uint32_t LocaleListCache::getId(const std::string& locales) { - LocaleListCache* inst = LocaleListCache::getInstance(); - std::unordered_map<std::string, uint32_t>::const_iterator it = - inst->mLocaleListLookupTable.find(locales); - if (it != inst->mLocaleListLookupTable.end()) { +LocaleListCache::LocaleListCache() { + // Insert an empty locale list for mapping default locale list to kEmptyListId. + // The default locale list has only one Locale and it is the unsupported locale. + mLocaleLists.emplace_back(); + mLocaleListLookupTable.insert(std::make_pair("", kEmptyListId)); +} + +uint32_t LocaleListCache::getIdInternal(const std::string& locales) { + std::lock_guard<std::mutex> lock(mMutex); + const auto& it = mLocaleListLookupTable.find(locales); + if (it != mLocaleListLookupTable.end()) { return it->second; } // Given locale list is not in cache. Insert it and return newly assigned ID. - const uint32_t nextId = inst->mLocaleLists.size(); + const uint32_t nextId = mLocaleLists.size(); LocaleList fontLocales(parseLocaleList(locales)); if (fontLocales.empty()) { return kEmptyListId; } - inst->mLocaleLists.push_back(std::move(fontLocales)); - inst->mLocaleListLookupTable.insert(std::make_pair(locales, nextId)); + mLocaleLists.push_back(std::move(fontLocales)); + mLocaleListLookupTable.insert(std::make_pair(locales, nextId)); return nextId; } -// static -const LocaleList& LocaleListCache::getById(uint32_t id) { - LocaleListCache* inst = LocaleListCache::getInstance(); - MINIKIN_ASSERT(id < inst->mLocaleLists.size(), "Lookup by unknown locale list ID."); - return inst->mLocaleLists[id]; -} - -// static -LocaleListCache* LocaleListCache::getInstance() { - assertMinikinLocked(); - static LocaleListCache* instance = nullptr; - if (instance == nullptr) { - instance = new LocaleListCache(); - - // Insert an empty locale list for mapping default locale list to kEmptyListId. - // The default locale list has only one Locale and it is the unsupported locale. - instance->mLocaleLists.push_back(LocaleList()); - instance->mLocaleListLookupTable.insert(std::make_pair("", kEmptyListId)); - } - return instance; +const LocaleList& LocaleListCache::getByIdInternal(uint32_t id) { + std::lock_guard<std::mutex> lock(mMutex); + MINIKIN_ASSERT(id < mLocaleLists.size(), "Lookup by unknown locale list ID."); + return mLocaleLists[id]; } } // namespace minikin diff --git a/libs/minikin/LocaleListCache.h b/libs/minikin/LocaleListCache.h index 9ebb111..2a007af 100644 --- a/libs/minikin/LocaleListCache.h +++ b/libs/minikin/LocaleListCache.h @@ -17,6 +17,7 @@ #ifndef MINIKIN_LOCALE_LIST_CACHE_H #define MINIKIN_LOCALE_LIST_CACHE_H +#include <mutex> #include <unordered_map> #include "Locale.h" @@ -35,22 +36,36 @@ public: // Returns the locale list ID for the given string representation of LocaleList. // Caller should acquire a lock before calling the method. - static uint32_t getId(const std::string& locales); + static inline uint32_t getId(const std::string& locales) { + return getInstance().getIdInternal(locales); + } // Caller should acquire a lock before calling the method. - static const LocaleList& getById(uint32_t id); + static inline const LocaleList& getById(uint32_t id) { + return getInstance().getByIdInternal(id); + } private: - LocaleListCache() {} // Singleton + LocaleListCache(); // Singleton ~LocaleListCache() {} + uint32_t getIdInternal(const std::string& locales); + const LocaleList& getByIdInternal(uint32_t id); + // Caller should acquire a lock before calling the method. - static LocaleListCache* getInstance(); + static LocaleListCache& getInstance() { + static LocaleListCache instance; + return instance; + } std::vector<LocaleList> mLocaleLists; // A map from the string representation of the font locale list to the ID. std::unordered_map<std::string, uint32_t> mLocaleListLookupTable; + + // To avoid dead-locking, need to acquire gMinikinLock before acquiring mMutex. + // TODO: Remove gMinikinLock + std::mutex mMutex; }; } // namespace minikin |