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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user