From d2740de55efc52e8dc9270c0e17db921a379a049 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Wed, 18 Sep 2013 16:03:20 +0000 Subject: [PATCH] Make _() and friends safe to call from any thread. The GetUntranslatedString() hack keeps a global copy of all strings, so that it can return a const reference as wxGetTranslation() return value. A global wxHashSet instance shared by all threads won't do, even guarded with a critical section, because it may internally copy values on any insert and thus invalidate pointers that may still be used on another thread. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74833 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/private/threadinfo.h | 12 ++++++++++++ interface/wx/translation.h | 12 +++++++++++- src/common/translation.cpp | 16 +++++----------- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 1391d17ec7..1eef4dd943 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -568,6 +568,7 @@ All: - Fix build with wxUSE_FFILE==0 (jroemmler). - Add wxDEPRECATED_MSG() and use it in a few places. - Return the old file descriptor/pointer from wx(F)File::Detach() (troelsk). +- _() and wxGetTranslation() are now thread-safe. All (GUI): diff --git a/include/wx/private/threadinfo.h b/include/wx/private/threadinfo.h index 500af5dd9c..1ff241bda8 100644 --- a/include/wx/private/threadinfo.h +++ b/include/wx/private/threadinfo.h @@ -14,6 +14,13 @@ class WXDLLIMPEXP_FWD_BASE wxLog; +#if wxUSE_INTL +#include "wx/hashset.h" +WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, + wxLocaleUntranslatedStrings); +#endif + + // ---------------------------------------------------------------------------- // wxThreadSpecificInfo: contains all thread-specific information used by wx // ---------------------------------------------------------------------------- @@ -40,6 +47,11 @@ public: // logging bool loggingDisabled; +#if wxUSE_INTL + // Storage for wxTranslations::GetUntranslatedString() + wxLocaleUntranslatedStrings untranslatedStrings; +#endif + private: wxThreadSpecificInfo() : logger(NULL), loggingDisabled(false) {} }; diff --git a/interface/wx/translation.h b/interface/wx/translation.h index dcd46bed10..96cb74f985 100644 --- a/interface/wx/translation.h +++ b/interface/wx/translation.h @@ -234,6 +234,8 @@ public: error message is generated the first time a string is not found; use wxLogNull to suppress it). + This function is thread-safe. + @remarks Domains are searched in the last to first order, i.e. catalogs added later override those added before. */ @@ -264,6 +266,8 @@ public: See GNU gettext manual for additional information on plural forms handling. This method is called by the wxGetTranslation() function and _() macro. + This function is thread-safe. + @remarks Domains are searched in the last to first order, i.e. catalogs added later override those added before. */ @@ -515,6 +519,8 @@ public: This function calls wxTranslations::GetString(). + This function is thread-safe. + @note This function is not suitable for literal strings in Unicode builds since the literal strings must be enclosed in wxT() macro which makes them unrecognised by @c xgettext, and so they are not extracted to @@ -546,7 +552,9 @@ const wxString& wxGetTranslation(const wxString& string, For a shorter alternative see the wxPLURAL() macro. - This function calls wxLocale::GetString(). + This function calls wxTranslation::GetString(). + + This function is thread-safe. @header{wx/intl.h} */ @@ -562,6 +570,8 @@ const wxString& wxGetTranslation(const wxString& string, also returns the translation of the string for the current locale during execution. + This macro is thread-safe. + @header{wx/intl.h} */ const wxString& _(const wxString& string); diff --git a/src/common/translation.cpp b/src/common/translation.cpp index 8816c08013..e4bee82b3d 100644 --- a/src/common/translation.cpp +++ b/src/common/translation.cpp @@ -47,7 +47,7 @@ #include "wx/tokenzr.h" #include "wx/fontmap.h" #include "wx/stdpaths.h" -#include "wx/hashset.h" +#include "wx/private/threadinfo.h" #ifdef __WINDOWS__ #include "wx/dynlib.h" @@ -1605,20 +1605,14 @@ wxString wxTranslations::GetBestTranslation(const wxString& domain, } -namespace -{ -WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, - wxLocaleUntranslatedStrings); -} - /* static */ const wxString& wxTranslations::GetUntranslatedString(const wxString& str) { - static wxLocaleUntranslatedStrings s_strings; + wxLocaleUntranslatedStrings& strings = wxThreadInfo.untranslatedStrings; - wxLocaleUntranslatedStrings::iterator i = s_strings.find(str); - if ( i == s_strings.end() ) - return *s_strings.insert(str).first; + wxLocaleUntranslatedStrings::iterator i = strings.find(str); + if ( i == strings.end() ) + return *strings.insert(str).first; return *i; } -- 2.45.2