]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/thread.cpp
applied patch 890642: wxRE_ADVANCED flag and docs
[wxWidgets.git] / src / msw / thread.cpp
index 0ac242717792968e369bcfeb18fa9ed0d39e3282..469ced786b44ebabbe4ea8866e854061e55e4e0c 100644 (file)
@@ -300,7 +300,7 @@ private:
 
 wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount)
 {
-#ifndef __WXWINCE__
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300)
     if ( maxcount == 0 )
     {
         // make it practically infinite
@@ -353,7 +353,7 @@ wxSemaError wxSemaphoreInternal::WaitTimeout(unsigned long milliseconds)
 
 wxSemaError wxSemaphoreInternal::Post()
 {
-#ifndef __WXWINCE__
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300)
     if ( !::ReleaseSemaphore(m_semaphore, 1, NULL /* ptr to previous count */) )
 #endif
     {
@@ -484,7 +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
-    if ( thread->m_internal->GetState() == STATE_EXITED )
+    bool isExited = (thread->m_internal->GetState() == STATE_EXITED);
+
+    if ( isExited )
     {
         rc = (THREAD_RETVAL)-1;
     }
@@ -499,17 +501,23 @@ THREAD_RETVAL THREAD_CALLCONV wxThreadInternal::WinThreadStart(void *param)
         }
 
         rc = (THREAD_RETVAL)thread->Entry();
+    }
+
+    thread->OnExit();
+
+    // save IsDetached because thread object can be deleted by joinable
+    // threads after state is changed to STATE_EXITED.
+    bool isDetached = thread->IsDetached();
 
+    if (!isExited)
+    {
         // enter m_critsect before changing the thread state
         wxCriticalSectionLocker lock(thread->m_critsect);
-
         thread->m_internal->SetState(STATE_EXITED);
     }
 
-    thread->OnExit();
-
     // the thread may delete itself now if it wants, we don't need it any more
-    thread->m_internal->LetDie();
+    if (isDetached) thread->m_internal->LetDie();
 
     return rc;
 }
@@ -690,7 +698,7 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
         // process the Windows messages that result from these functions
         // (note that even in console applications we might have to process
         // messages if we use wxExecute() or timers or ...)
-        DWORD result = 0;       // suppress warnings from broken compilers
+        DWORD result wxDUMMY_INITIALIZE(0);
         do
         {
             if ( wxThread::IsMain() )
@@ -769,15 +777,24 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs,
     // 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
     // terminated if the "if" above hadn't been taken
-    do
+    for ( ;; )
     {
         if ( !::GetExitCodeThread(m_hThread, (LPDWORD)&rc) )
         {
             wxLogLastError(wxT("GetExitCodeThread"));
 
             rc = (wxThread::ExitCode)-1;
+
+            break;
         }
-    } while ( (DWORD)rc == STILL_ACTIVE );
+
+        if ( (DWORD)rc != STILL_ACTIVE )
+            break;
+
+        // give the other thread some time to terminate, otherwise we may be
+        // starving it
+        ::Sleep(1);
+    }
 
     if ( pRc )
         *pRc = rc;
@@ -885,7 +902,7 @@ bool wxThread::SetConcurrency(size_t level)
 
     // get system affinity mask first
     HANDLE hProcess = ::GetCurrentProcess();
-    DWORD dwProcMask, dwSysMask;
+    DWORD_PTR dwProcMask, dwSysMask;
     if ( ::GetProcessAffinityMask(hProcess, &dwProcMask, &dwSysMask) == 0 )
     {
         wxLogLastError(_T("GetProcessAffinityMask"));
@@ -966,7 +983,8 @@ bool wxThread::SetConcurrency(size_t level)
 
         return false;
     }
-#endif
+#endif // !__WXWINCE__
+
     return true;
 }