diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2021-11-10 17:02:52 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2021-11-10 18:15:22 +0100 |
commit | 6334f7dc43f69ada4341d5f0dd1a0f1e13113b4f (patch) | |
tree | a2bd5a414876db8fcc70dbe03d1a01d455091985 /i18nlangtag | |
parent | 0ac45af39c534ce17a4a76a370add4ffa4fa92f9 (diff) |
initialization-order-fiasco, again
...after b5758cb2729236d9eaf52bd25b1b113a3ff06b4e "rtl::Static to thread-safe
static" (which this partially reverts again), like
71d0c43fb4cf535239cb41baf7b6e03de765ce7a "initialization-order-fiasco" in the
past
Change-Id: Ie3f352a63ee3939b1727faf6cf11b2768173437c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124998
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'i18nlangtag')
-rw-r--r-- | i18nlangtag/source/languagetag/languagetag.cxx | 107 |
1 files changed, 54 insertions, 53 deletions
diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx index 83d730f5fc5f..6f6a766e861f 100644 --- a/i18nlangtag/source/languagetag/languagetag.cxx +++ b/i18nlangtag/source/languagetag/languagetag.cxx @@ -18,6 +18,7 @@ #include <sal/log.hxx> #include <osl/file.hxx> #include <osl/mutex.hxx> +#include <rtl/instance.hxx> #include <rtl/locale.h> #include <tools/long.hxx> #include <algorithm> @@ -49,32 +50,42 @@ struct myLtError }; // "static" to be returned as const reference to an empty locale. -const lang::Locale theEmptyLocale; +struct theEmptyLocale : public rtl::Static< lang::Locale, theEmptyLocale > {}; +} typedef std::unordered_set< OUString > KnownTagSet; +namespace { +struct theKnowns : public rtl::Static< KnownTagSet, theKnowns > {}; +struct theMutex : public rtl::Static< osl::Mutex, theMutex > {}; +} -const KnownTagSet & getKnowns() +static const KnownTagSet & getKnowns() { - static KnownTagSet theKnowns = []() + KnownTagSet & rKnowns = theKnowns::get(); + if (rKnowns.empty()) { - KnownTagSet ret; - ::std::vector< MsLangId::LanguagetagMapping > aDefined( MsLangId::getDefinedLanguagetags()); - for (auto const& elemDefined : aDefined) + osl::MutexGuard aGuard( theMutex::get()); + if (rKnowns.empty()) { - // Do not use the BCP47 string here to initialize the - // LanguageTag because then canonicalize() would call this - // getKnowns() again... - ::std::vector< OUString > aFallbacks( LanguageTag( elemDefined.mnLang).getFallbackStrings( true)); - for (auto const& fallback : aFallbacks) + ::std::vector< MsLangId::LanguagetagMapping > aDefined( MsLangId::getDefinedLanguagetags()); + for (auto const& elemDefined : aDefined) { - ret.insert(fallback); + // Do not use the BCP47 string here to initialize the + // LanguageTag because then canonicalize() would call this + // getKnowns() again... + ::std::vector< OUString > aFallbacks( LanguageTag( elemDefined.mnLang).getFallbackStrings( true)); + for (auto const& fallback : aFallbacks) + { + rKnowns.insert(fallback); + } } } - return ret; - }(); - return theKnowns; + } + return rKnowns; } + +namespace { struct compareIgnoreAsciiCaseLess { bool operator()( const OUString& r1, std::u16string_view r2 ) const @@ -84,23 +95,17 @@ struct compareIgnoreAsciiCaseLess }; typedef ::std::map< OUString, LanguageTag::ImplPtr, compareIgnoreAsciiCaseLess > MapBcp47; typedef ::std::map< LanguageType, LanguageTag::ImplPtr > MapLangID; -MapBcp47 theMapBcp47; -MapLangID theMapLangID; -LanguageTag::ImplPtr theDontKnow; -LanguageTag::ImplPtr theSystemLocale; -osl::Mutex& theMutex() -{ - static osl::Mutex SINGLETON; - return SINGLETON; -} - +struct theMapBcp47 : public rtl::Static< MapBcp47, theMapBcp47 > {}; +struct theMapLangID : public rtl::Static< MapLangID, theMapLangID > {}; +struct theDontKnow : public rtl::Static< LanguageTag::ImplPtr, theDontKnow > {}; +struct theSystemLocale : public rtl::Static< LanguageTag::ImplPtr, theSystemLocale > {}; } static LanguageType getNextOnTheFlyLanguage() { static LanguageType nOnTheFlyLanguage(0); - osl::MutexGuard aGuard(theMutex()); + osl::MutexGuard aGuard( theMutex::get()); if (!nOnTheFlyLanguage) nOnTheFlyLanguage = MsLangId::makeLangID( LANGUAGE_ON_THE_FLY_SUB_START, LANGUAGE_ON_THE_FLY_START); else @@ -166,11 +171,7 @@ private: static void teardown(); }; -LiblangtagDataRef& theDataRef() -{ - static LiblangtagDataRef SINGLETON; - return SINGLETON; -} +struct theDataRef : public rtl::Static< LiblangtagDataRef, theDataRef > {}; } LiblangtagDataRef::LiblangtagDataRef() @@ -428,7 +429,7 @@ LanguageTagImpl::LanguageTagImpl( const LanguageTagImpl & rLanguageTagImpl ) mbCachedGlibcString( rLanguageTagImpl.mbCachedGlibcString) { if (mpImplLangtag) - theDataRef().init(); + theDataRef::get().init(); } @@ -464,7 +465,7 @@ LanguageTagImpl& LanguageTagImpl::operator=( const LanguageTagImpl & rLanguageTa mbCachedVariants = rLanguageTagImpl.mbCachedVariants; mbCachedGlibcString = rLanguageTagImpl.mbCachedGlibcString; if (mpImplLangtag && !oldTag) - theDataRef().init(); + theDataRef::get().init(); return *this; } @@ -595,9 +596,9 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID return pImpl; } - osl::MutexGuard aGuard( theMutex()); + osl::MutexGuard aGuard( theMutex::get()); - MapBcp47& rMapBcp47 = theMapBcp47; + MapBcp47& rMapBcp47 = theMapBcp47::get(); MapBcp47::const_iterator it( rMapBcp47.find( maBcp47)); bool bOtherImpl = false; if (it != rMapBcp47.end()) @@ -633,7 +634,7 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID // different, otherwise we would end up with ambiguous assignments // of different language tags, for example for the same primary // LangID with "no", "nb" and "nn". - const MapLangID& rMapLangID = theMapLangID; + const MapLangID& rMapLangID = theMapLangID::get(); MapLangID::const_iterator itID( rMapLangID.find( nRegisterID)); if (itID != rMapLangID.end()) { @@ -666,7 +667,7 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID } ::std::pair< MapLangID::const_iterator, bool > res( - theMapLangID.insert( ::std::make_pair( pImpl->mnLangID, pImpl))); + theMapLangID::get().insert( ::std::make_pair( pImpl->mnLangID, pImpl))); if (res.second) { SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: cross-inserted 0x" @@ -685,7 +686,7 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID LanguageTag::ScriptType LanguageTag::getOnTheFlyScriptType( LanguageType nRegisterID ) { - const MapLangID& rMapLangID = theMapLangID; + const MapLangID& rMapLangID = theMapLangID::get(); MapLangID::const_iterator itID( rMapLangID.find( nRegisterID)); if (itID != rMapLangID.end()) return (*itID).second->getScriptType(); @@ -708,7 +709,7 @@ void LanguageTag::setConfiguredSystemLanguage( LanguageType nLang ) MsLangId::LanguageTagAccess::setConfiguredSystemLanguage( nLang); // Reset system locale to none and let registerImpl() do the rest to // initialize a new one. - theSystemLocale.reset(); + theSystemLocale::get().reset(); LanguageTag aLanguageTag( LANGUAGE_SYSTEM); aLanguageTag.registerImpl(); } @@ -748,7 +749,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const // and take the system locale shortcut if possible. if (mbSystemLocale) { - pImpl = theSystemLocale; + pImpl = theSystemLocale::get(); if (pImpl) { #if OSL_DEBUG_LEVEL > 0 @@ -773,7 +774,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const // Heavy usage of LANGUAGE_DONTKNOW, make it an own Impl for all the // conversion attempts. At the same time provide a central breakpoint // to inspect such places. - LanguageTag::ImplPtr& rDontKnow = theDontKnow; + LanguageTag::ImplPtr& rDontKnow = theDontKnow::get(); if (!rDontKnow) rDontKnow = std::make_shared<LanguageTagImpl>( *this); pImpl = rDontKnow; @@ -787,7 +788,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const else { // A great share are calls for a system equal locale. - pImpl = theSystemLocale; + pImpl = theSystemLocale::get(); if (pImpl && pImpl->mnLangID == mnLangID) { #if OSL_DEBUG_LEVEL > 0 @@ -818,7 +819,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const if (mbInitializedBcp47) { // A great share are calls for a system equal locale. - pImpl = theSystemLocale; + pImpl = theSystemLocale::get(); if (pImpl && pImpl->maBcp47 == maBcp47) { #if OSL_DEBUG_LEVEL > 0 @@ -836,7 +837,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: " << nCallsNonSystem << " non-system calls"); #endif - osl::MutexGuard aGuard( theMutex()); + osl::MutexGuard aGuard( theMutex::get()); #if OSL_DEBUG_LEVEL > 0 static tools::Long nRunning = 0; @@ -851,7 +852,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const // Prefer LangID map as find+insert needs less comparison work. if (mbInitializedLangID) { - MapLangID& rMap = theMapLangID; + MapLangID& rMap = theMapLangID::get(); MapLangID::const_iterator it( rMap.find( mnLangID)); if (it != rMap.end()) { @@ -873,7 +874,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const if (!pImpl->mbInitializedBcp47) pImpl->convertLocaleToBcp47(); ::std::pair< MapBcp47::const_iterator, bool > res( - theMapBcp47.insert( ::std::make_pair( pImpl->maBcp47, pImpl))); + theMapBcp47::get().insert( ::std::make_pair( pImpl->maBcp47, pImpl))); if (res.second) { SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: cross-inserted '" << pImpl->maBcp47 << "' for 0x" << ::std::hex << mnLangID); @@ -894,7 +895,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const } else if (!maBcp47.isEmpty()) { - MapBcp47& rMap = theMapBcp47; + MapBcp47& rMap = theMapBcp47::get(); MapBcp47::const_iterator it( rMap.find( maBcp47)); if (it != rMap.end()) { @@ -956,7 +957,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const if (bInsert) { ::std::pair< MapLangID::const_iterator, bool > res( - theMapLangID.insert( ::std::make_pair( pImpl->mnLangID, pImpl))); + theMapLangID::get().insert( ::std::make_pair( pImpl->mnLangID, pImpl))); if (res.second) { SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: cross-inserted 0x" @@ -988,7 +989,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const // above, so add it. if (mbSystemLocale && mbInitializedLangID) { - theSystemLocale = pImpl; + theSystemLocale::get() = pImpl; SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: added system locale 0x" << ::std::hex << pImpl->mnLangID << " '" << pImpl->maBcp47 << "'"); } @@ -1210,7 +1211,7 @@ bool LanguageTagImpl::canonicalize() if (!mpImplLangtag) { - theDataRef().init(); + theDataRef::get().init(); mpImplLangtag = lt_tag_new(); } @@ -1526,7 +1527,7 @@ void LanguageTag::convertFromRtlLocale() * string. */ #if 0 myLtError aError; - theDataRef().init(); + theDataRef::get().init(); mpImplLangtag = lt_tag_convert_from_locale( aStr.getStr(), &aError.p); maBcp47 = OStringToOUString( lt_tag_get_string( mpImplLangtag), RTL_TEXTENCODING_UTF8); mbInitializedBcp47 = true; @@ -1698,7 +1699,7 @@ OUString LanguageTagImpl::getVariantsFromLangtag() const css::lang::Locale & LanguageTag::getLocale( bool bResolveSystem ) const { if (!bResolveSystem && mbSystemLocale) - return theEmptyLocale; + return theEmptyLocale::get(); if (!mbInitializedLocale) syncVarsFromImpl(); if (!mbInitializedLocale) @@ -2831,7 +2832,7 @@ bool LanguageTag::isValidBcp47( const OUString& rString, OUString* o_pCanonicali lt_tag_t* mpLangtag; guard() { - theDataRef().init(); + theDataRef::get().init(); mpLangtag = lt_tag_new(); } ~guard() |