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
This commit is contained in:
@@ -599,11 +599,6 @@ private:
|
|||||||
// not by the compiler), the global s_cache variable could be not yet
|
// 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
|
// initialized when a ctor of another global object is executed and if that
|
||||||
// ctor uses any wxString methods, bad things happen
|
// 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 Cache& GetCache()
|
||||||
{
|
{
|
||||||
static wxTLS_TYPE(Cache) s_cache;
|
static wxTLS_TYPE(Cache) s_cache;
|
||||||
@@ -615,6 +610,13 @@ private:
|
|||||||
static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; }
|
static Cache::Element *GetCacheEnd() { return GetCacheBegin() + Cache::SIZE; }
|
||||||
static unsigned& LastUsedCacheElement() { return GetCache().lastUsed; }
|
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;
|
friend struct wxStrCacheDumper;
|
||||||
|
|
||||||
// uncomment this to have access to some profiling statistics on program
|
// uncomment this to have access to some profiling statistics on program
|
||||||
|
@@ -60,10 +60,25 @@ const size_t wxString::npos = (size_t) -1;
|
|||||||
|
|
||||||
#if wxUSE_STRING_POS_CACHE
|
#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
|
// 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
|
// not my 6.4.98 version under amd64, so provide this debugging helper to do it
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct wxStrCacheDumper
|
struct wxStrCacheDumper
|
||||||
{
|
{
|
||||||
static void ShowAll()
|
static void ShowAll()
|
||||||
@@ -85,6 +100,8 @@ struct wxStrCacheDumper
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
void wxDumpStrCache() { wxStrCacheDumper::ShowAll(); }
|
void wxDumpStrCache() { wxStrCacheDumper::ShowAll(); }
|
||||||
|
|
||||||
#endif // __WXDEBUG__
|
#endif // __WXDEBUG__
|
||||||
|
Reference in New Issue
Block a user