+// ----------------------------------------------------------------------------
+// wxCriticalSection implementation
+// ----------------------------------------------------------------------------
+
+wxCriticalSection::wxCriticalSection()
+{
+ m_critsect = new wxCriticalSectionInternal;
+}
+
+wxCriticalSection::~wxCriticalSection()
+{
+ delete m_critsect;
+}
+
+void wxCriticalSection::Enter()
+{
+ ::DosEnterCritSec();
+}
+
+void wxCriticalSection::Leave()
+{
+ ::DosExitCritSec();
+}
+
+// ----------------------------------------------------------------------------
+// wxThread implementation
+// ----------------------------------------------------------------------------
+
+// wxThreadInternal class
+// ----------------------
+
+class wxThreadInternal
+{
+public:
+ inline wxThreadInternal()
+ {
+ m_hThread = 0;
+ m_eState = STATE_NEW;
+ m_nPriority = 0;
+ }
+
+ // create a new (suspended) thread (for the given thread object)
+ bool Create(wxThread* pThread);
+
+ // suspend/resume/terminate
+ bool Suspend();
+ bool Resume();
+ inline void Cancel() { m_eState = STATE_CANCELED; }
+
+ // thread state
+ inline void SetState(wxThreadState eState) { m_eState = eState; }
+ inline wxThreadState GetState() const { return m_eState; }
+
+ // thread priority
+ inline void SetPriority(unsigned int nPriority) { m_nPriority = nPriority; }
+ inline unsigned int GetPriority() const { return m_nPriority; }
+
+ // thread handle and id
+ inline TID GetHandle() const { return m_hThread; }
+ TID GetId() const { return m_hThread; }
+
+ // thread function
+ static DWORD OS2ThreadStart(wxThread *thread);
+
+private:
+ // Threads in OS/2 have only an ID, so m_hThread is both it's handle and ID
+ // PM also has no real Tls mechanism to index pointers by so we'll just
+ // keep track of the wxWindows parent object here.
+ TID m_hThread; // handle and ID of the thread
+ wxThreadState m_eState; // state, see wxThreadState enum
+ unsigned int m_nPriority; // thread priority in "wx" units
+};
+
+ULONG wxThreadInternal::OS2ThreadStart(
+ wxThread* pThread
+)
+{
+ m_pThread = pThread;
+
+ DWORD dwRet = (DWORD)pThread->Entry();
+
+ pThread->p_internal->SetState(STATE_EXITED);
+ pThread->OnExit();
+
+ delete pThread;
+ m_pThread = NULL;
+ return dwRet;
+}
+
+bool wxThreadInternal::Create(
+ wxThread* pThread
+)
+{
+ APIRET ulrc;
+
+ ulrc = ::DosCreateThread( &m_hThread
+ ,(PFNTHREAD)wxThreadInternal::OS2ThreadStart
+ ,(ULONG)pThread
+ ,CREATE_SUSPENDED | STACK_SPARSE
+ ,8192L
+ );
+ if(ulrc != 0)
+ {
+ wxLogSysError(_("Can't create thread"));
+
+ return FALSE;
+ }
+
+ // translate wxWindows priority to the PM one
+ ULONG ulOS2_Priority;
+
+ if (m_nPriority <= 20)
+ ulOS2_Priority = PRTYC_NOCHANGE;
+ else if (m_nPriority <= 40)
+ ulOS2_Priority = PRTYC_IDLETIME;
+ else if (m_nPriority <= 60)
+ ulOS2_Priority = PRTYC_REGULAR;
+ else if (m_nPriority <= 80)
+ ulOS2_Priority = PRTYC_TIMECRITICAL;
+ else if (m_nPriority <= 100)
+ ulOS2_Priority = PRTYC_FOREGROUNDSERVER;
+ else
+ {
+ wxFAIL_MSG(wxT("invalid value of thread priority parameter"));
+ ulOS2_Priority = PRTYC_REGULAR;
+ }
+ ulrc = ::DosSetPriority( PRTYS_THREAD
+ ,ulOS2_Priority
+ ,0
+ ,(ULONG)m_hThread
+ );
+ if (ulrc != 0)
+ {
+ wxLogSysError(_("Can't set thread priority"));
+ }
+ return TRUE;
+}
+
+bool wxThreadInternal::Suspend()
+{
+ ULONG ulrc = ::DosSuspendThread(m_hThread);
+
+ if (ulrc != 0)
+ {
+ wxLogSysError(_("Can not suspend thread %lu"), m_hThread);
+ return FALSE;
+ }
+ m_eState = STATE_PAUSED;
+ return TRUE;
+}
+
+bool wxThreadInternal::Resume()
+{
+ ULONG ulrc = ::DosResumeThread(m_hThread);
+
+ if (ulrc != 0)
+ {
+ wxLogSysError(_("Can not suspend thread %lu"), m_hThread);
+ return FALSE;
+ }
+ m_eState = STATE_PAUSED;
+ return TRUE;
+}
+
+// static functions
+// ----------------
+
+wxThread *wxThread::This()
+{
+ wxThread* pThread = m_pThread;
+ 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
+
+void wxThread::Yield()
+{
+ ::DosSleep(0);
+}
+
+void wxThread::Sleep(
+ unsigned long ulMilliseconds
+)
+{
+ ::DosSleep(ulMilliseconds);
+}
+
+// create/start thread
+// -------------------
+