+ULONG wxThreadInternal::OS2ThreadStart(
+ wxThread* pThread
+)
+{
+ m_pThread = pThread;
+
+ DWORD dwRet = (DWORD)pThread->Entry();
+
+ // enter m_critsect before changing the thread state
+ pThread->m_critsect.Enter();
+
+ bool bWasCancelled = pThread->m_internal->GetState() == STATE_CANCELED;
+
+ pThread->m_internal->SetState(STATE_EXITED);
+ pThread->m_critsect.Leave();
+
+ pThread->OnExit();
+
+ // if the thread was cancelled (from Delete()), then it the handle is still
+ // needed there
+ if (pThread->IsDetached() && !bWasCancelled)
+ {
+ // auto delete
+ delete pThread;
+ }
+ //else: the joinable threads handle will be closed when Wait() is done
+ return dwRet;
+}
+
+void wxThreadInternal::SetPriority(
+ unsigned int nPriority
+)
+{
+ // translate wxWindows priority to the PM one
+ ULONG ulOS2_Priority;
+ ULONG ulrc;
+
+ m_nPriority = nPriority;
+
+ 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"));
+ }
+}
+
+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;
+ }
+ if (m_nPriority != WXTHREAD_DEFAULT_PRIORITY)
+ {
+ SetPriority(m_nPriority);
+ }
+ 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);
+}
+
+// ctor and dtor
+// -------------
+
+wxThread::wxThread(wxThreadKind kind)
+{
+ m_internal = new wxThreadInternal();
+
+ m_isDetached = kind == wxTHREAD_DETACHED;
+}
+
+wxThread::~wxThread()
+{
+ delete m_internal;
+}
+
+// create/start thread
+// -------------------
+