diff options
author | Daniel Wilhelm <daniel@wili.li> | 2016-05-31 16:38:45 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2016-05-31 16:38:45 +0200 |
commit | be08c6c09a3026da628daf2425516beda1557bb3 (patch) | |
tree | 062cc2f6a1e5ba5a2fdcb53549cc09c4ff5d062a /zen/i18n.h | |
parent | 8.1 (diff) | |
download | FreeFileSync-be08c6c09a3026da628daf2425516beda1557bb3.tar.gz FreeFileSync-be08c6c09a3026da628daf2425516beda1557bb3.tar.bz2 FreeFileSync-be08c6c09a3026da628daf2425516beda1557bb3.zip |
8.2
Diffstat (limited to 'zen/i18n.h')
-rw-r--r-- | zen/i18n.h | 40 |
1 files changed, 27 insertions, 13 deletions
@@ -45,7 +45,7 @@ private: }; void setTranslator(std::unique_ptr<const TranslationHandler>&& newHandler); //take ownership -const TranslationHandler* getTranslator(); +std::shared_ptr<const TranslationHandler> getTranslator(); @@ -65,7 +65,7 @@ namespace implementation inline std::wstring translate(const std::wstring& text) { - if (const TranslationHandler* t = getTranslator()) + if (std::shared_ptr<const TranslationHandler> t = getTranslator()) //std::shared_ptr => temporarily take (shared) ownership while using the interface! return t->translate(text); return text; @@ -79,7 +79,7 @@ std::wstring translate(const std::wstring& singular, const std::wstring& plural, { assert(contains(plural, L"%x")); - if (const TranslationHandler* t = getTranslator()) + if (std::shared_ptr<const TranslationHandler> t = getTranslator()) { std::wstring translation = t->translate(singular, plural, n); assert(!contains(translation, L"%x")); @@ -99,11 +99,12 @@ std::wstring translate(const std::wstring& singular, const std::wstring& plural, inline -const TranslationHandler*& getTranslationInstance() +std::shared_ptr<const TranslationHandler>*& getTranslationInstance() { - //avoid static destruction order fiasco: there may be accesses to "getTranslator()" during process shutdown e.g. show message in debug_minidump.cpp! - //=> use POD instead of a std::unique_ptr<>!!! - static const TranslationHandler* inst = nullptr; //external linkage even in header! + //avoid static destruction order fiasco: there may be accesses to "getTranslator()" during process shutdown + //e.g. show message in debug_minidump.cpp or some detached thread assembling an error message! + //=> use POD instead of a plain std::shared_ptr<>!!! + static std::shared_ptr<const TranslationHandler>* inst = nullptr; //external linkage even in header! return inst; } @@ -112,28 +113,41 @@ struct CleanUpTranslationHandler { ~CleanUpTranslationHandler() { - const TranslationHandler*& handler = getTranslationInstance(); - assert(!handler); //clean up at a better time rather than during static destruction! potential MT issues!? + std::shared_ptr<const TranslationHandler>*& handler = getTranslationInstance(); + assert(!handler); //clean up at a better time rather than during static destruction! MT issues! delete handler; handler = nullptr; //getTranslator() may be called even after static objects of this translation unit are destroyed! } }; } +//setTranslator/getTranslator() operating on a global are obviously racy for MT usage +//=> make them fast to cover the rare case of a language change and the not-so-rare case of language clean-up during shutdown +//=> can't synchronize with std::mutex which is non-POD and again leads to global destruction order fiasco +//=> return std::shared_ptr to let instance life time be handled by caller (MT!) inline void setTranslator(std::unique_ptr<const TranslationHandler>&& newHandler) { static implementation::CleanUpTranslationHandler cuth; //external linkage even in header! - const TranslationHandler*& handler = implementation::getTranslationInstance(); - delete handler; - handler = newHandler.release(); + std::shared_ptr<const TranslationHandler>*& handler = implementation::getTranslationInstance(); + auto tmp = handler; + handler = nullptr; + delete tmp; + if (newHandler) + handler = new std::shared_ptr<const TranslationHandler>(std::move(newHandler)); } inline -const TranslationHandler* getTranslator() { return implementation::getTranslationInstance(); } +std::shared_ptr<const TranslationHandler> getTranslator() +{ + std::shared_ptr<const TranslationHandler>*& handler = implementation::getTranslationInstance(); + if (handler) + return *handler; + return nullptr; +} } #endif //I18_N_H_3843489325044253425456 |