]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/thread.cpp
fixed typo in including function.tex
[wxWidgets.git] / src / msw / thread.cpp
index e839cba462fd5852529f22c00c6afdfda2e83ffe..2180ddd994e8a548c97498fb39de7e8eb51b61aa 100644 (file)
@@ -32,6 +32,7 @@
 #if wxUSE_THREADS
 
 #include "wx/msw/private.h"
+#include "wx/msw/missing.h"
 
 #include "wx/module.h"
 #include "wx/thread.h"
@@ -964,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() )
         {
@@ -985,7 +1008,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
         // 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
-        DWORD result;
+        DWORD result = 0;       // suppress warnings from broken compilers
         do
         {
             if ( IsMain() )
@@ -1021,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;