+wxThreadError wxThread::Kill()
+{
+ wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR,
+ _T("a thread can't kill itself") );
+
+ switch ( m_internal->GetState() )
+ {
+ case STATE_NEW:
+ case STATE_EXITED:
+ return wxTHREAD_NOT_RUNNING;
+
+ case STATE_PAUSED:
+ // resume the thread first
+ Resume();
+
+ // fall through
+
+ default:
+ OSStatus err = MPTerminateTask( m_internal->GetId() , -1 ) ;
+ if ( err )
+ {
+ wxLogError(_("Failed to terminate a thread."));
+
+ return wxTHREAD_MISC_ERROR;
+ }
+
+ if ( m_isDetached )
+ {
+ delete this ;
+ }
+ else
+ {
+ // this should be retrieved by Wait actually
+ m_internal->SetExitCode((void*)-1);
+ }
+
+ return wxTHREAD_NO_ERROR;
+ }
+}
+
+void wxThread::Exit(ExitCode status)
+{
+ wxASSERT_MSG( This() == this,
+ _T("wxThread::Exit() can only be called in the context of the same thread") );
+
+ // don't enter m_critsect before calling OnExit() because the user code
+ // might deadlock if, for example, it signals a condition in OnExit() (a
+ // common case) while the main thread calls any of functions entering
+ // m_critsect on us (almost all of them do)
+ OnExit();
+
+ MPTaskID threadid = m_internal->GetId() ;
+
+ if ( IsDetached() )
+ {
+ delete this;
+ }
+ else // joinable
+ {
+ // update the status of the joinable thread
+ wxCriticalSectionLocker lock(m_critsect);
+ m_internal->SetState(STATE_EXITED);
+ }
+ MPTerminateTask( threadid , (long) status) ;
+}
+
+// also test whether we were paused
+bool wxThread::TestDestroy()
+{
+ wxASSERT_MSG( This() == this,
+ _T("wxThread::TestDestroy() can only be called in the context of the same thread") );
+
+ m_critsect.Enter();
+
+ if ( m_internal->GetState() == STATE_PAUSED )
+ {
+ m_internal->SetReallyPaused(TRUE);
+
+ // leave the crit section or the other threads will stop too if they
+ // try to call any of (seemingly harmless) IsXXX() functions while we
+ // sleep
+ m_critsect.Leave();
+
+ m_internal->Pause();
+ }
+ else
+ {
+ // thread wasn't requested to pause, nothing to do
+ m_critsect.Leave();
+ }
+
+ return m_internal->WasCancelled();
+}
+
+// -----------------------------------------------------------------------------
+// priority setting
+// -----------------------------------------------------------------------------
+
+void wxThread::SetPriority(unsigned int prio)
+{
+ wxCHECK_RET( ((int)WXTHREAD_MIN_PRIORITY <= (int)prio) &&
+ ((int)prio <= (int)WXTHREAD_MAX_PRIORITY),
+ wxT("invalid thread priority") );
+
+ wxCriticalSectionLocker lock(m_critsect);
+
+ switch ( m_internal->GetState() )
+ {
+ case STATE_RUNNING:
+ case STATE_PAUSED:
+ case STATE_NEW:
+ // thread not yet started, priority will be set when it is
+ m_internal->SetPriority(prio);
+ break;
+
+ case STATE_EXITED:
+ default:
+ wxFAIL_MSG(wxT("impossible to set thread priority in this state"));
+ }
+}
+
+unsigned int wxThread::GetPriority() const
+{
+ wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
+
+ return m_internal->GetPriority();
+}
+
+unsigned long wxThread::GetId() const
+{
+ wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
+
+ return (unsigned long)m_internal->GetId();
+}
+
+// -----------------------------------------------------------------------------
+// state tests
+// -----------------------------------------------------------------------------
+
+bool wxThread::IsRunning() const
+{
+ wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
+
+ return m_internal->GetState() == STATE_RUNNING;
+}
+
+bool wxThread::IsAlive() const
+{
+ wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect);
+
+ switch ( m_internal->GetState() )
+ {
+ case STATE_RUNNING:
+ case STATE_PAUSED:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+bool wxThread::IsPaused() const
+{
+ wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect);
+
+ return (m_internal->GetState() == STATE_PAUSED);
+}
+
+// ----------------------------------------------------------------------------
+// Automatic initialization for thread module
+// ----------------------------------------------------------------------------
+
+class wxThreadModule : public wxModule
+{