wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount)
{
-#ifndef __WXWINCE__
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300)
if ( maxcount == 0 )
{
// make it practically infinite
wxSemaError wxSemaphoreInternal::Post()
{
-#ifndef __WXWINCE__
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300)
if ( !::ReleaseSemaphore(m_semaphore, 1, NULL /* ptr to previous count */) )
#endif
{
// 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;
}
}
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;
}
{
m_priority = priority;
- // translate wxWindows priority to the Windows one
+ // translate wxWidgets priority to the Windows one
int win_priority;
if (m_priority <= 20)
win_priority = THREAD_PRIORITY_LOWEST;
//
// NB: we still must include QS_ALLINPUT even when waiting
// in a secondary thread because if it had created some
- // window somehow (possible not even using wxWindows)
+ // window somehow (possible not even using wxWidgets)
// the system might dead lock then
if ( wxThread::IsMain() )
{
// 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;
bool wxThread::IsMain()
{
- return ::GetCurrentThreadId() == gs_idMainThread;
+ return ::GetCurrentThreadId() == gs_idMainThread || gs_idMainThread == 0;
}
void wxThread::Yield()
bool wxThread::SetConcurrency(size_t level)
{
-#ifndef __WXWINCE__
+#ifdef __WXWINCE__
+ wxUnusedVar(level);
+ return false;
+#else
wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
// ok only for the default one
// get system affinity mask first
HANDLE hProcess = ::GetCurrentProcess();
- DWORD dwProcMask, dwSysMask;
+ DWORD_PTR dwProcMask, dwSysMask;
if ( ::GetProcessAffinityMask(hProcess, &dwProcMask, &dwSysMask) == 0 )
{
wxLogLastError(_T("GetProcessAffinityMask"));
return false;
}
-#endif
+
return true;
+#endif // __WXWINCE__/!__WXWINCE__
}
// ctor and dtor