Add missing critical section locking before accessing shared variable.

WinThreadStart() in wxMSW wxThread implementation accessed the variable
containing the thread state without locking which was wrong, do it only inside
the critical section.

Notice that there is still an unavoidable race condition between exiting the
thread and starting it, so it's not clear at all if we should try to avoid
calling DoThreadStart() here.

Closes #14865.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73125 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2012-12-04 00:39:33 +00:00
parent 55fd62c1e3
commit 3fb8a2bcfb

View File

@@ -589,9 +589,14 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
// each thread has its own SEH translator so install our own a.s.a.p. // each thread has its own SEH translator so install our own a.s.a.p.
DisableAutomaticSETranslator(); DisableAutomaticSETranslator();
// NB: Notice that we can't use wxCriticalSectionLocker in this function as
// we use SEH and it's incompatible with C++ object dtors.
// first of all, check whether we hadn't been cancelled already and don't // first of all, check whether we hadn't been cancelled already and don't
// start the user code at all then // start the user code at all then
thread->m_critsect.Enter();
const bool hasExited = thread->m_internal->GetState() == STATE_EXITED; const bool hasExited = thread->m_internal->GetState() == STATE_EXITED;
thread->m_critsect.Leave();
// run the thread function itself inside a SEH try/except block // run the thread function itself inside a SEH try/except block
wxSEH_TRY wxSEH_TRY
@@ -609,10 +614,6 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
const bool isDetached = thread->IsDetached(); const bool isDetached = thread->IsDetached();
if ( !hasExited ) if ( !hasExited )
{ {
// enter m_critsect before changing the thread state
//
// NB: can't use wxCriticalSectionLocker here as we use SEH and it's
// incompatible with C++ object dtors
thread->m_critsect.Enter(); thread->m_critsect.Enter();
thread->m_internal->SetState(STATE_EXITED); thread->m_internal->SetState(STATE_EXITED);
thread->m_critsect.Leave(); thread->m_critsect.Leave();