Merge branch 'msw-thread-tls-fix-and-cleanup'

Minor cleanup in wxMSW wxThread code.

See https://github.com/wxWidgets/wxWidgets/pull/2327
This commit is contained in:
Vadim Zeitlin
2021-04-16 22:30:38 +01:00

View File

@@ -90,8 +90,9 @@ enum wxThreadState
// this module globals // this module globals
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TLS index of the slot where we store the pointer to the current thread // TLS index of the slot where we store the pointer to the current thread, the
static DWORD gs_tlsThisThread = 0xFFFFFFFF; // initial value is special and means that it's not initialized yet
static DWORD gs_tlsThisThread = TLS_OUT_OF_INDEXES;
// id of the main thread - the one which can call GUI functions without first // id of the main thread - the one which can call GUI functions without first
// calling wxMutexGuiEnter() // calling wxMutexGuiEnter()
@@ -108,11 +109,6 @@ static wxCriticalSection *gs_critsectGui = NULL;
// critical section which protects gs_nWaitingForGui variable // critical section which protects gs_nWaitingForGui variable
static wxCriticalSection *gs_critsectWaitingForGui = NULL; static wxCriticalSection *gs_critsectWaitingForGui = NULL;
// critical section which serializes WinThreadStart() and WaitForTerminate()
// (this is a potential bottleneck, we use a single crit sect for all threads
// in the system, but normally time spent inside it should be quite short)
static wxCriticalSection *gs_critsectThreadDelete = NULL;
// number of threads waiting for GUI in wxMutexGuiEnter() // number of threads waiting for GUI in wxMutexGuiEnter()
static size_t gs_nWaitingForGui = 0; static size_t gs_nWaitingForGui = 0;
@@ -525,6 +521,9 @@ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread)
wxTRY wxTRY
{ {
// store the thread object in the TLS // store the thread object in the TLS
wxASSERT_MSG( gs_tlsThisThread != TLS_OUT_OF_INDEXES,
"TLS index not set. Is wx initialized?" );
if ( !::TlsSetValue(gs_tlsThisThread, thread) ) if ( !::TlsSetValue(gs_tlsThisThread, thread) )
{ {
wxLogSysError(_("Cannot start thread: error writing TLS.")); wxLogSysError(_("Cannot start thread: error writing TLS."));
@@ -913,6 +912,8 @@ bool wxThreadInternal::Resume()
wxThread *wxThread::This() wxThread *wxThread::This()
{ {
wxASSERT_MSG( gs_tlsThisThread != TLS_OUT_OF_INDEXES,
"TLS index not set. Is wx initialized?" );
wxThread *thread = (wxThread *)::TlsGetValue(gs_tlsThisThread); wxThread *thread = (wxThread *)::TlsGetValue(gs_tlsThisThread);
// be careful, 0 may be a valid return value as well // be careful, 0 may be a valid return value as well
@@ -1226,7 +1227,7 @@ bool wxThreadModule::OnInit()
{ {
// allocate TLS index for storing the pointer to the current thread // allocate TLS index for storing the pointer to the current thread
gs_tlsThisThread = ::TlsAlloc(); gs_tlsThisThread = ::TlsAlloc();
if ( gs_tlsThisThread == 0xFFFFFFFF ) if ( gs_tlsThisThread == TLS_OUT_OF_INDEXES )
{ {
// in normal circumstances it will only happen if all other // in normal circumstances it will only happen if all other
// TLS_MINIMUM_AVAILABLE (>= 64) indices are already taken - in other // TLS_MINIMUM_AVAILABLE (>= 64) indices are already taken - in other
@@ -1241,7 +1242,7 @@ bool wxThreadModule::OnInit()
if ( !::TlsSetValue(gs_tlsThisThread, (LPVOID)0) ) if ( !::TlsSetValue(gs_tlsThisThread, (LPVOID)0) )
{ {
::TlsFree(gs_tlsThisThread); ::TlsFree(gs_tlsThisThread);
gs_tlsThisThread = 0xFFFFFFFF; gs_tlsThisThread = TLS_OUT_OF_INDEXES;
wxLogSysError(_("Thread module initialization failed: cannot store value in thread local storage")); wxLogSysError(_("Thread module initialization failed: cannot store value in thread local storage"));
@@ -1253,8 +1254,6 @@ bool wxThreadModule::OnInit()
gs_critsectGui = new wxCriticalSection(); gs_critsectGui = new wxCriticalSection();
gs_critsectGui->Enter(); gs_critsectGui->Enter();
gs_critsectThreadDelete = new wxCriticalSection;
wxThread::ms_idMainThread = wxThread::GetCurrentId(); wxThread::ms_idMainThread = wxThread::GetCurrentId();
return true; return true;
@@ -1267,7 +1266,10 @@ void wxThreadModule::OnExit()
wxLogLastError(wxT("TlsFree failed.")); wxLogLastError(wxT("TlsFree failed."));
} }
wxDELETE(gs_critsectThreadDelete); // invalidate slot index to make the errors more obvious if we try to use
// it from now on, e.g. if any wxThreads are still running (which shouldn't
// be the case, of course, but might still happen)
gs_tlsThisThread = TLS_OUT_OF_INDEXES;
if ( gs_critsectGui ) if ( gs_critsectGui )
{ {