]> git.saurik.com Git - wxWidgets.git/commitdiff
call GetCache() from a global object ctor to ensure that it is done before any thread...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 31 Aug 2008 14:57:53 +0000 (14:57 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 31 Aug 2008 14:57:53 +0000 (14:57 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55393 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/string.h
src/common/string.cpp

index 9cbcc49a2893e276de05969efb3c15c9da9c8846..d8aebef9acfe025b306cb7bae211038a07bb244f 100644 (file)
@@ -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
   // 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;
   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; }
 
   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
   friend struct wxStrCacheDumper;
 
   // uncomment this to have access to some profiling statistics on program
index 85b30905335d5583528b65729888a2060b7f6829..827099f0a611bd82f7329006aeca04923e3d8ea8 100644 (file)
@@ -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
 // not my 6.4.98 version under amd64, so provide this debugging helper to do it
 #ifdef __WXDEBUG__
 
 // 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()
 struct wxStrCacheDumper
 {
     static void ShowAll()
@@ -85,6 +100,8 @@ struct wxStrCacheDumper
     }
 };
 
     }
 };
 
+} // anonymous namespace
+
 void wxDumpStrCache() { wxStrCacheDumper::ShowAll(); }
 
 #endif // __WXDEBUG__
 void wxDumpStrCache() { wxStrCacheDumper::ShowAll(); }
 
 #endif // __WXDEBUG__