Fix crash when using wxThreadSpecificInfo from global object ctor.
When not using compiler TLS support (which is the default now), TLS variable itself needs to be initialized and user-defined code in the global objects ctor could be called before this happened, resulting in using uninitialized CRITICAL_SECTION under Windows and a crash. Fix this by wrapping global wxThreadSpecificInfo itself in an accessor function ensuring that it is always initialized before use. Notice that this required adding wxTLS_TYPE_REF() as wxTLS_TYPE() itself can't be used for the function return value (__thread or similar can only be used on the variables). Closes #16009. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75949 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
d08b801d2c
commit
e518e31acd
@ -44,6 +44,7 @@
|
||||
|
||||
#ifdef wxHAS_COMPILER_TLS
|
||||
#define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
|
||||
#define wxTLS_TYPE_REF(T) T&
|
||||
#define wxTLS_PTR(var) (&(var))
|
||||
#define wxTLS_VALUE(var) (var)
|
||||
#else // !wxHAS_COMPILER_TLS
|
||||
@ -135,6 +136,7 @@
|
||||
};
|
||||
|
||||
#define wxTLS_TYPE(T) wxTlsValue<T>
|
||||
#define wxTLS_TYPE_REF(T) wxTLS_TYPE(T)&
|
||||
#define wxTLS_PTR(var) ((var).Get())
|
||||
#define wxTLS_VALUE(var) (*(var))
|
||||
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
|
||||
|
@ -48,26 +48,33 @@ inline wxAllThreadInfos& GetAllThreadInfos()
|
||||
}
|
||||
|
||||
// Pointer to the current thread's instance
|
||||
wxTLS_TYPE(wxThreadSpecificInfo*) g_thisThreadInfo;
|
||||
inline wxTLS_TYPE_REF(wxThreadSpecificInfo*) GetThisThreadInfo()
|
||||
{
|
||||
static wxTLS_TYPE(wxThreadSpecificInfo*) s_thisThreadInfo;
|
||||
|
||||
return s_thisThreadInfo;
|
||||
}
|
||||
|
||||
#define wxTHIS_THREAD_INFO wxTLS_VALUE(GetThisThreadInfo())
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
wxThreadSpecificInfo& wxThreadSpecificInfo::Get()
|
||||
{
|
||||
if ( !wxTLS_VALUE(g_thisThreadInfo) )
|
||||
if ( !wxTHIS_THREAD_INFO )
|
||||
{
|
||||
wxTLS_VALUE(g_thisThreadInfo) = new wxThreadSpecificInfo;
|
||||
wxTHIS_THREAD_INFO = new wxThreadSpecificInfo;
|
||||
wxCriticalSectionLocker lock(GetAllThreadInfosCS());
|
||||
GetAllThreadInfos().push_back(
|
||||
wxSharedPtr<wxThreadSpecificInfo>(wxTLS_VALUE(g_thisThreadInfo)));
|
||||
wxSharedPtr<wxThreadSpecificInfo>(wxTHIS_THREAD_INFO));
|
||||
}
|
||||
return *wxTLS_VALUE(g_thisThreadInfo);
|
||||
return *wxTHIS_THREAD_INFO;
|
||||
}
|
||||
|
||||
void wxThreadSpecificInfo::ThreadCleanUp()
|
||||
{
|
||||
if ( !wxTLS_VALUE(g_thisThreadInfo) )
|
||||
if ( !wxTHIS_THREAD_INFO )
|
||||
return; // nothing to do, not used by this thread at all
|
||||
|
||||
// find this thread's instance in GetAllThreadInfos() and destroy it
|
||||
@ -76,10 +83,10 @@ void wxThreadSpecificInfo::ThreadCleanUp()
|
||||
i != GetAllThreadInfos().end();
|
||||
++i )
|
||||
{
|
||||
if ( i->get() == wxTLS_VALUE(g_thisThreadInfo) )
|
||||
if ( i->get() == wxTHIS_THREAD_INFO )
|
||||
{
|
||||
GetAllThreadInfos().erase(i);
|
||||
wxTLS_VALUE(g_thisThreadInfo) = NULL;
|
||||
wxTHIS_THREAD_INFO = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user