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
|
#ifdef wxHAS_COMPILER_TLS
|
||||||
#define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
|
#define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
|
||||||
|
#define wxTLS_TYPE_REF(T) T&
|
||||||
#define wxTLS_PTR(var) (&(var))
|
#define wxTLS_PTR(var) (&(var))
|
||||||
#define wxTLS_VALUE(var) (var)
|
#define wxTLS_VALUE(var) (var)
|
||||||
#else // !wxHAS_COMPILER_TLS
|
#else // !wxHAS_COMPILER_TLS
|
||||||
@ -135,6 +136,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define wxTLS_TYPE(T) wxTlsValue<T>
|
#define wxTLS_TYPE(T) wxTlsValue<T>
|
||||||
|
#define wxTLS_TYPE_REF(T) wxTLS_TYPE(T)&
|
||||||
#define wxTLS_PTR(var) ((var).Get())
|
#define wxTLS_PTR(var) ((var).Get())
|
||||||
#define wxTLS_VALUE(var) (*(var))
|
#define wxTLS_VALUE(var) (*(var))
|
||||||
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
|
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
|
||||||
|
@ -48,26 +48,33 @@ inline wxAllThreadInfos& GetAllThreadInfos()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pointer to the current thread's instance
|
// 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
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
wxThreadSpecificInfo& wxThreadSpecificInfo::Get()
|
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());
|
wxCriticalSectionLocker lock(GetAllThreadInfosCS());
|
||||||
GetAllThreadInfos().push_back(
|
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()
|
void wxThreadSpecificInfo::ThreadCleanUp()
|
||||||
{
|
{
|
||||||
if ( !wxTLS_VALUE(g_thisThreadInfo) )
|
if ( !wxTHIS_THREAD_INFO )
|
||||||
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 GetAllThreadInfos() and destroy it
|
// find this thread's instance in GetAllThreadInfos() and destroy it
|
||||||
@ -76,10 +83,10 @@ void wxThreadSpecificInfo::ThreadCleanUp()
|
|||||||
i != GetAllThreadInfos().end();
|
i != GetAllThreadInfos().end();
|
||||||
++i )
|
++i )
|
||||||
{
|
{
|
||||||
if ( i->get() == wxTLS_VALUE(g_thisThreadInfo) )
|
if ( i->get() == wxTHIS_THREAD_INFO )
|
||||||
{
|
{
|
||||||
GetAllThreadInfos().erase(i);
|
GetAllThreadInfos().erase(i);
|
||||||
wxTLS_VALUE(g_thisThreadInfo) = NULL;
|
wxTHIS_THREAD_INFO = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user