From 077309e1a38c65d7d236f06b4d54e67ffcf897bf Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Thu, 4 Jul 2002 09:07:15 +0000 Subject: [PATCH] Applied patch from Mark Armstrong This patch fixes two problems. The first is a race condition during a thread exit and a join. The second is condition where a thread can hang during msg/event processing. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16031 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/thread.cpp | 49 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index d93d017704..2180ddd994 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -965,8 +965,30 @@ wxThreadError wxThread::Delete(ExitCode *pRc) HANDLE hThread = m_internal->GetHandle(); - // does is still run? - if ( isRunning || IsRunning() ) + // Check if thread is really still running. There is a + // race condition in WinThreadStart between the time the + // m_internal->m_state is set to STATE_EXITED and the win32 + // thread actually exits. It can be flagged as STATE_EXITED + // and then we don't wait for it to exit. This will cause + // GetExitCodeThread to return STILL_ACTIVE. + if ( !isRunning ) + { + if ( !IsRunning() ) + { + if ( ::GetExitCodeThread(hThread, (LPDWORD)&rc) ) + { + if ((DWORD)rc == STILL_ACTIVE) + isRunning = TRUE; + } + } + else + { + isRunning = TRUE; + } + } + + // does it still run? + if ( isRunning ) { if ( IsMain() ) { @@ -1022,13 +1044,24 @@ wxThreadError wxThread::Delete(ExitCode *pRc) break; case WAIT_OBJECT_0 + 1: - // new message arrived, process it - if ( !wxTheApp->DoMessage() ) { - // WM_QUIT received: kill the thread - Kill(); - - return wxTHREAD_KILLED; + MSG peekMsg; + // Check if a new message has really arrived. + // MsgWaitForMultipleObjects can indicate that a message + // is ready for processing, but this message may be sucked + // up by GetMessage and then GetMessage will hang and not + // allow us to process the actual thread exit event. + if (::PeekMessage(&peekMsg, (HWND) NULL, 0, 0, PM_NOREMOVE)) + { + // new message arrived, process it + if ( !wxTheApp->DoMessage() ) + { + // WM_QUIT received: kill the thread + Kill(); + + return wxTHREAD_KILLED; + } + } } break; -- 2.45.2