diff options
Diffstat (limited to 'zen/i18n.h')
-rw-r--r-- | zen/i18n.h | 52 |
1 files changed, 11 insertions, 41 deletions
@@ -1,15 +1,15 @@ -// ************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * -// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** +// ***************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * +// ***************************************************************************** #ifndef I18_N_H_3843489325044253425456 #define I18_N_H_3843489325044253425456 #include <string> -#include <memory> #include <cstdint> +#include "globals.h" #include "string_tools.h" #include "format_unit.h" @@ -67,7 +67,6 @@ std::wstring translate(const std::wstring& text) { 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; } @@ -99,55 +98,26 @@ std::wstring translate(const std::wstring& singular, const std::wstring& plural, inline -std::shared_ptr<const TranslationHandler>*& getTranslationInstance() +Global<const TranslationHandler>& refTranslationGlobals() { - //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! + //getTranslator() may be called even after static objects of this translation unit are destroyed! + static Global<const TranslationHandler> inst; //external linkage even in header! return inst; } - - -struct CleanUpTranslationHandler -{ - ~CleanUpTranslationHandler() - { - std::shared_ptr<const TranslationHandler>*& handler = getTranslationInstance(); - assert(!handler); //clean up at a better time rather than during static destruction! MT issues! - auto oldHandler = handler; - handler = nullptr; //getTranslator() may be called even after static objects of this translation unit are destroyed! - delete oldHandler; - } -}; } -//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! - - std::shared_ptr<const TranslationHandler>*& handler = implementation::getTranslationInstance(); - auto oldHandler = handler; - handler = nullptr; - delete oldHandler; - if (newHandler) - handler = new std::shared_ptr<const TranslationHandler>(std::move(newHandler)); + implementation::refTranslationGlobals().set(std::move(newHandler)); } inline std::shared_ptr<const TranslationHandler> getTranslator() { - std::shared_ptr<const TranslationHandler>*& handler = implementation::getTranslationInstance(); - if (handler) - return *handler; - return nullptr; + return implementation::refTranslationGlobals().get(); } } |