Wait() should now return correct exit code even if thread state was EXITED (replaces patch 1166425)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33007 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -484,9 +484,9 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
|
||||
|
||||
// first of all, check whether we hadn't been cancelled already and don't
|
||||
// start the user code at all then
|
||||
bool isExited = (thread->m_internal->GetState() == STATE_EXITED);
|
||||
const bool hasExited = thread->m_internal->GetState() == STATE_EXITED;
|
||||
|
||||
if ( isExited )
|
||||
if ( hasExited )
|
||||
{
|
||||
rc = (THREAD_RETVAL)-1;
|
||||
}
|
||||
@@ -509,7 +509,7 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
|
||||
// threads after state is changed to STATE_EXITED.
|
||||
bool isDetached = thread->IsDetached();
|
||||
|
||||
if (!isExited)
|
||||
if ( !hasExited )
|
||||
{
|
||||
// enter m_critsect before changing the thread state
|
||||
wxCriticalSectionLocker lock(thread->m_critsect);
|
||||
@@ -517,7 +517,8 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
|
||||
}
|
||||
|
||||
// the thread may delete itself now if it wants, we don't need it any more
|
||||
if (isDetached) thread->m_internal->LetDie();
|
||||
if ( isDetached )
|
||||
thread->m_internal->LetDie();
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -633,14 +634,11 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
|
||||
|
||||
wxThread::ExitCode rc = 0;
|
||||
|
||||
// Delete() is always safe to call, so consider all possible states
|
||||
// we might need to resume the thread if it's currently stopped
|
||||
bool shouldResume = false;
|
||||
|
||||
// we might need to resume the thread, but we might also not need to cancel
|
||||
// it if it doesn't run yet
|
||||
bool shouldResume = false,
|
||||
isRunning = false;
|
||||
|
||||
// check if the thread already started to run
|
||||
// as Delete() (which calls us) is always safe to call we need to consider
|
||||
// all possible states
|
||||
{
|
||||
wxCriticalSectionLocker lock(cs);
|
||||
|
||||
@@ -653,20 +651,17 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
|
||||
// to let it run
|
||||
m_state = STATE_EXITED;
|
||||
|
||||
Resume(); // it knows about STATE_EXITED special case
|
||||
|
||||
// we must call Resume() as the thread hasn't been initially
|
||||
// resumed yet (and as Resume() it knows about STATE_EXITED
|
||||
// special case, it won't touch it and WinThreadStart() will
|
||||
// just exit immediately)
|
||||
shouldResume = true;
|
||||
shouldDelete = false;
|
||||
}
|
||||
|
||||
isRunning = true;
|
||||
|
||||
// shouldResume is correctly set to false here
|
||||
//else: shouldResume is correctly set to false here, wait until
|
||||
// someone else runs the thread and it finishes
|
||||
}
|
||||
else if ( m_state == STATE_EXITED )
|
||||
{
|
||||
return wxTHREAD_NOT_RUNNING;
|
||||
}
|
||||
else // running (but maybe paused or cancelled)
|
||||
else // running, paused, cancelled or even exited
|
||||
{
|
||||
shouldResume = m_state == STATE_PAUSED;
|
||||
}
|
||||
@@ -676,15 +671,6 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
|
||||
if ( shouldResume )
|
||||
Resume();
|
||||
|
||||
// is it still running?
|
||||
if ( isRunning || m_state == STATE_RUNNING )
|
||||
{
|
||||
if ( wxThread::IsMain() )
|
||||
{
|
||||
// set flag for wxIsWaitingForThread()
|
||||
gs_waitingForThread = true;
|
||||
}
|
||||
|
||||
// ask the thread to terminate
|
||||
if ( shouldDelete )
|
||||
{
|
||||
@@ -693,6 +679,14 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
|
||||
Cancel();
|
||||
}
|
||||
|
||||
|
||||
// now wait for thread to finish
|
||||
if ( wxThread::IsMain() )
|
||||
{
|
||||
// set flag for wxIsWaitingForThread()
|
||||
gs_waitingForThread = true;
|
||||
}
|
||||
|
||||
// we can't just wait for the thread to terminate because it might be
|
||||
// calling some GUI functions and so it will never terminate before we
|
||||
// process the Windows messages that result from these functions
|
||||
@@ -772,7 +766,7 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
|
||||
{
|
||||
gs_waitingForThread = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// although the thread might be already in the EXITED state it might not
|
||||
// have terminated yet and so we are not sure that it has actually
|
||||
@@ -834,7 +828,7 @@ bool wxThreadInternal::Resume()
|
||||
|
||||
// don't change the state from STATE_EXITED because it's special and means
|
||||
// we are going to terminate without running any user code - if we did it,
|
||||
// the codei n Delete() wouldn't work
|
||||
// the code in WaitForTerminate() wouldn't work
|
||||
if ( m_state != STATE_EXITED )
|
||||
{
|
||||
m_state = STATE_RUNNING;
|
||||
|
Reference in New Issue
Block a user