// Author: Original from Wolfram Gloger/Guilhem Lavaux/David Webster
// Modified by: Stefan Neis
// Created: 04/22/98
-// RCS-ID: $Id$
// Copyright: (c) Stefan Neis (2003)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/log.h"
+ #include "wx/app.h"
+ #include "wx/module.h"
#endif //WX_PRECOMP
-#include "wx/app.h"
#include "wx/apptrait.h"
-#include "wx/module.h"
#include "wx/utils.h"
#include <stdio.h>
// id of the main thread - the one which can call GUI functions without first
// calling wxMutexGuiEnter()
-static ULONG s_ulIdMainThread = 1;
+wxThreadIdType wxThread::ms_idMainThread = 0;
wxMutex* p_wxMainMutex;
// OS2 substitute for Tls pointer the current parent thread object
bool IsOk() const { return m_vMutex != NULL; }
wxMutexError Lock() { return LockTimeout(SEM_INDEFINITE_WAIT); }
- wxMutexError TryLock() { return LockTimeout(SEM_IMMEDIATE_RETURN); }
+ wxMutexError Lock(unsigned long ms) { return LockTimeout(ms); }
+ wxMutexError TryLock();
wxMutexError Unlock();
private:
APIRET ulrc = ::DosCreateMutexSem(NULL, &m_vMutex, 0L, FALSE);
if (ulrc != 0)
{
- wxLogSysError(_("Can not create mutex."));
+ wxLogSysError(_("Cannot create mutex."));
m_vMutex = NULL;
}
}
if (m_vMutex)
{
if (::DosCloseMutexSem(m_vMutex))
- wxLogLastError(_T("DosCloseMutexSem(mutex)"));
+ {
+ wxLogLastError(wxT("DosCloseMutexSem(mutex)"));
+ }
}
}
+wxMutexError wxMutexInternal::TryLock()
+{
+ const wxMutexError rc = LockTimeout( SEM_IMMEDIATE_RETURN );
+
+ // we have a special return code for timeout in this case
+ return rc == wxMUTEX_TIMEOUT ? wxMUTEX_BUSY : rc;
+}
+
wxMutexError wxMutexInternal::LockTimeout(ULONG ulMilliseconds)
{
APIRET ulrc;
switch (ulrc)
{
case ERROR_TIMEOUT:
+ return wxMUTEX_TIMEOUT;
case ERROR_TOO_MANY_SEM_REQUESTS:
return wxMUTEX_BUSY;
ulrc = ::DosCreateMutexSem(NULL, &m_vMutex, 0L, FALSE);
if (ulrc != 0)
{
- wxLogLastError(_T("DosCreateMutexSem()"));
+ wxLogLastError(wxT("DosCreateMutexSem()"));
m_vMutex = NULL;
m_vEvent = NULL;
return;
ulrc = ::DosCreateEventSem(NULL, &m_vEvent, 0L, FALSE);
if ( ulrc != 0)
{
- wxLogLastError(_T("DosCreateEventSem()"));
+ wxLogLastError(wxT("DosCreateEventSem()"));
::DosCloseMutexSem(m_vMutex);
m_vMutex = NULL;
m_vEvent = NULL;
{
if ( ::DosCloseEventSem(m_vEvent) )
{
- wxLogLastError(_T("DosCloseEventSem(semaphore)"));
+ wxLogLastError(wxT("DosCloseEventSem(semaphore)"));
}
if ( ::DosCloseMutexSem(m_vMutex) )
{
- wxLogLastError(_T("DosCloseMutexSem(semaphore)"));
+ wxLogLastError(wxT("DosCloseMutexSem(semaphore)"));
}
else
m_vEvent = NULL;
return wxSEMA_TIMEOUT;
default:
- wxLogLastError(_T("DosWaitEventSem(semaphore)"));
+ wxLogLastError(wxT("DosWaitEventSem(semaphore)"));
return wxSEMA_MISC_ERROR;
}
ulrc = :: DosRequestMutexSem(m_vMutex, ulMilliseconds);
return wxSEMA_OVERFLOW;
if ( ulrc != NO_ERROR && ulrc != ERROR_ALREADY_POSTED )
{
- wxLogLastError(_T("DosPostEventSem(semaphore)"));
+ wxLogLastError(wxT("DosPostEventSem(semaphore)"));
return wxSEMA_MISC_ERROR;
}
{
m_hThread = 0;
m_eState = STATE_NEW;
- m_nPriority = WXTHREAD_DEFAULT_PRIORITY;
+ m_nPriority = wxPRIORITY_DEFAULT;
}
~wxThreadInternal()
return false;
}
m_hThread = tid;
- if (m_nPriority != WXTHREAD_DEFAULT_PRIORITY)
+ if (m_nPriority != wxPRIORITY_DEFAULT)
{
SetPriority(m_nPriority);
}
if (ulrc != 0)
{
- wxLogSysError(_("Can not suspend thread %lu"), m_hThread);
+ wxLogSysError(_("Cannot suspend thread %lu"), m_hThread);
return false;
}
m_eState = STATE_PAUSED;
if (ulrc != 0)
{
- wxLogSysError(_("Can not resume thread %lu"), m_hThread);
+ wxLogSysError(_("Cannot resume thread %lu"), m_hThread);
return false;
}
return pThread;
}
-bool wxThread::IsMain()
-{
- PTIB ptib;
- PPIB ppib;
-
- ::DosGetInfoBlocks(&ptib, &ppib);
-
- if (ptib->tib_ptib2->tib2_ultid == s_ulIdMainThread)
- return true;
-
- return false;
-}
-
#ifdef Yield
#undef Yield
#endif
::DosSleep(0);
}
-void wxThread::Sleep(
- unsigned long ulMilliseconds
-)
-{
- ::DosSleep(ulMilliseconds);
-}
-
int wxThread::GetCPUCount()
{
ULONG CPUCount;
return CPUCount;
}
-unsigned long wxThread::GetCurrentId()
+wxThreadIdType wxThread::GetCurrentId()
{
PTIB ptib;
PPIB ppib;
::DosGetInfoBlocks(&ptib, &ppib);
- return (unsigned long) ptib->tib_ptib2->tib2_ultid;
+ return (wxThreadIdType) ptib->tib_ptib2->tib2_ultid;
}
bool wxThread::SetConcurrency(size_t level)
{
- wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
+ wxASSERT_MSG( IsMain(), wxT("should only be called from the main thread") );
// ok only for the default one
if ( level == 0 )
{
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+ // Create the thread if it wasn't created yet with an explicit
+ // Create() call:
+ if ( !m_internal->GetHandle() )
+ {
+ if ( !m_internal->Create(this, 0) )
+ return wxTHREAD_NO_RESOURCE;
+ }
+
if ( m_internal->GetState() != STATE_NEW )
{
// actually, it may be almost any state at all, not only STATE_RUNNING
// stopping thread
// ---------------
-wxThread::ExitCode wxThread::Wait()
+wxThread::ExitCode wxThread::Wait(wxThreadWait waitMode)
{
// although under Windows we can wait for any thread, it's an error to
// wait for a detached one in wxWin API
wxCHECK_MSG( !IsDetached(), (ExitCode)-1,
- _T("can't wait for detached thread") );
+ wxT("can't wait for detached thread") );
ExitCode rc = (ExitCode)-1;
- (void)Delete(&rc);
+ (void)Delete(&rc, waitMode);
return(rc);
}
-wxThreadError wxThread::Delete(ExitCode *pRc)
+wxThreadError wxThread::Delete(ExitCode *pRc, wxThreadWait WXUNUSED(waitMode))
{
ExitCode rc = 0;
gs_pCritsectGui = new wxCriticalSection();
gs_pCritsectGui->Enter();
- PTIB ptib;
- PPIB ppib;
-
- ::DosGetInfoBlocks(&ptib, &ppib);
+ wxThread::ms_idMainThread = wxThread::GetCurrentId();
- s_ulIdMainThread = ptib->tib_ptib2->tib2_ultid;
return true;
}
#endif
}
-void WXDLLEXPORT wxMutexGuiEnter()
+void wxMutexGuiEnterImpl()
{
// this would dead lock everything...
wxASSERT_MSG( !wxThread::IsMain(),
gs_pCritsectGui->Enter();
}
-void WXDLLEXPORT wxMutexGuiLeave()
+void wxMutexGuiLeaveImpl()
{
wxCriticalSectionLocker enter(*gs_pCritsectWaitingForGui);