Fix crash when accessing wxThreadInfo during global initialization time.

We can't rely on our own globals being already constructed if we're called
during another global initialization, so use the usual trick with wrapping
them in accessor functions to ensure that they are.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74935 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2013-10-05 00:05:36 +00:00
parent 15a1c3b2ef
commit 52afc093fd

View File

@@ -28,11 +28,26 @@ namespace
// All thread info objects are stored in a global list so that they are // All thread info objects are stored in a global list so that they are
// freed when global objects are destroyed and no memory leaks are reported. // freed when global objects are destroyed and no memory leaks are reported.
wxCriticalSection g_csAllThreadInfos;
typedef wxVector< wxSharedPtr<wxThreadSpecificInfo> > wxAllThreadInfos;
wxAllThreadInfos g_allThreadInfos;
// Pointer to currenct thread's instance // Notice that we must be using accessor functions instead of simple global
// variables here as this code could be executed during global initialization
// time, i.e. before any globals in this module were initialzied.
inline wxCriticalSection& GetAllThreadInfosCS()
{
static wxCriticalSection s_csAllThreadInfos;
return s_csAllThreadInfos;
}
typedef wxVector< wxSharedPtr<wxThreadSpecificInfo> > wxAllThreadInfos;
inline wxAllThreadInfos& GetAllThreadInfos()
{
static wxAllThreadInfos s_allThreadInfos;
return s_allThreadInfos;
}
// Pointer to the current thread's instance
wxTLS_TYPE(wxThreadSpecificInfo*) g_thisThreadInfo; wxTLS_TYPE(wxThreadSpecificInfo*) g_thisThreadInfo;
} // anonymous namespace } // anonymous namespace
@@ -43,8 +58,8 @@ wxThreadSpecificInfo& wxThreadSpecificInfo::Get()
if ( !wxTLS_VALUE(g_thisThreadInfo) ) if ( !wxTLS_VALUE(g_thisThreadInfo) )
{ {
wxTLS_VALUE(g_thisThreadInfo) = new wxThreadSpecificInfo; wxTLS_VALUE(g_thisThreadInfo) = new wxThreadSpecificInfo;
wxCriticalSectionLocker lock(g_csAllThreadInfos); wxCriticalSectionLocker lock(GetAllThreadInfosCS());
g_allThreadInfos.push_back( GetAllThreadInfos().push_back(
wxSharedPtr<wxThreadSpecificInfo>(wxTLS_VALUE(g_thisThreadInfo))); wxSharedPtr<wxThreadSpecificInfo>(wxTLS_VALUE(g_thisThreadInfo)));
} }
return *wxTLS_VALUE(g_thisThreadInfo); return *wxTLS_VALUE(g_thisThreadInfo);
@@ -55,15 +70,15 @@ void wxThreadSpecificInfo::ThreadCleanUp()
if ( !wxTLS_VALUE(g_thisThreadInfo) ) if ( !wxTLS_VALUE(g_thisThreadInfo) )
return; // nothing to do, not used by this thread at all return; // nothing to do, not used by this thread at all
// find this thread's instance in g_allThreadInfos and destroy it // find this thread's instance in GetAllThreadInfos() and destroy it
wxCriticalSectionLocker lock(g_csAllThreadInfos); wxCriticalSectionLocker lock(GetAllThreadInfosCS());
for ( wxAllThreadInfos::iterator i = g_allThreadInfos.begin(); for ( wxAllThreadInfos::iterator i = GetAllThreadInfos().begin();
i != g_allThreadInfos.end(); i != GetAllThreadInfos().end();
++i ) ++i )
{ {
if ( i->get() == wxTLS_VALUE(g_thisThreadInfo) ) if ( i->get() == wxTLS_VALUE(g_thisThreadInfo) )
{ {
g_allThreadInfos.erase(i); GetAllThreadInfos().erase(i);
wxTLS_VALUE(g_thisThreadInfo) = NULL; wxTLS_VALUE(g_thisThreadInfo) = NULL;
break; break;
} }