]> git.saurik.com Git - wxWidgets.git/commitdiff
Add missing critical section locking before accessing shared variable.
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 4 Dec 2012 00:39:33 +0000 (00:39 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 4 Dec 2012 00:39:33 +0000 (00:39 +0000)
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

src/msw/thread.cpp

index 7213f4dc8e66d5333994c6494d6f92148ab87878..5c94b6066a52687ec8ddf874cb76f6a4409ba4ea 100644 (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.
     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
     // start the user code at all then
+    thread->m_critsect.Enter();
     const bool hasExited = thread->m_internal->GetState() == STATE_EXITED;
+    thread->m_critsect.Leave();
 
     // run the thread function itself inside a SEH try/except block
     wxSEH_TRY
@@ -609,10 +614,6 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
     const bool isDetached = thread->IsDetached();
     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_internal->SetState(STATE_EXITED);
         thread->m_critsect.Leave();