From: Vadim Zeitlin Date: Sun, 31 Aug 2008 14:57:53 +0000 (+0000) Subject: call GetCache() from a global object ctor to ensure that it is done before any thread... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/ad8ae78878ee48f0c4eb2deb0995ab07a1d23f72 call GetCache() from a global object ctor to ensure that it is done before any threads are created git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55393 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/string.h b/include/wx/string.h index 9cbcc49a28..d8aebef9ac 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -599,11 +599,6 @@ private: // not by the compiler), the global s_cache variable could be not yet // initialized when a ctor of another global object is executed and if that // ctor uses any wxString methods, bad things happen - // - // also note that for the same reason this function _is_ MT-safe: we know - // it's going to be called during the program startup (currently during - // globals initialization but even if they ever stop using wxString, it would - // still be called by wxInitialize()), i.e. before any threads are created static Cache& GetCache() { static wxTLS_TYPE(Cache) s_cache; @@ -615,6 +610,13 @@ private: static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; } static unsigned& LastUsedCacheElement() { return GetCache().lastUsed; } + // this helper struct is used to ensure that GetCache() is called during + // static initialization time, i.e. before any threads creation, as otherwise + // the static s_cache construction inside GetCache() wouldn't be MT-safe + friend struct wxStrCacheInitializer; + + // this is used in debug builds only to provide a convenient function, + // callable from a debugger, to show the cache contents friend struct wxStrCacheDumper; // uncomment this to have access to some profiling statistics on program diff --git a/src/common/string.cpp b/src/common/string.cpp index 85b3090533..827099f0a6 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -60,10 +60,25 @@ const size_t wxString::npos = (size_t) -1; #if wxUSE_STRING_POS_CACHE +struct wxStrCacheInitializer +{ + wxStrCacheInitializer() + { + // calling this function triggers s_cache initialization in it, and + // from now on it becomes safe to call from multiple threads + wxString::GetCache(); + } +}; + +static wxStrCacheInitializer gs_stringCacheInit; + // gdb seems to be unable to display thread-local variables correctly, at least // not my 6.4.98 version under amd64, so provide this debugging helper to do it #ifdef __WXDEBUG__ +namespace +{ + struct wxStrCacheDumper { static void ShowAll() @@ -85,6 +100,8 @@ struct wxStrCacheDumper } }; +} // anonymous namespace + void wxDumpStrCache() { wxStrCacheDumper::ShowAll(); } #endif // __WXDEBUG__