+static wxArrayPtrVoid s_threads ;
+
+ThreadEntryUPP wxThreadInternal::s_threadEntry = NULL ;
+pascal void* wxThreadInternal::MacThreadStart(wxThread *thread)
+{
+ // first of all, check whether we hadn't been cancelled already
+ if ( thread->m_internal->GetState() == STATE_EXITED )
+ {
+ return (void*)-1;
+ }
+
+ void* rc = thread->Entry();
+
+ // enter m_critsect before changing the thread state
+ thread->m_critsect.Enter();
+ bool wasCancelled = thread->m_internal->GetState() == STATE_CANCELED;
+ thread->m_internal->SetState(STATE_EXITED);
+ thread->m_critsect.Leave();
+
+ thread->OnExit();
+
+ // if the thread was cancelled (from Delete()), then it the handle is still
+ // needed there
+ if ( thread->IsDetached() && !wasCancelled )
+ {
+ // auto delete
+ delete thread;
+ }
+ //else: the joinable threads handle will be closed when Wait() is done
+
+ return rc;
+}
+void wxThreadInternal::SetPriority(unsigned int priority)
+{
+ // Priorities don't exist on Mac
+}
+
+bool wxThreadInternal::Create(wxThread *thread)
+{
+ if ( s_threadEntry == NULL )
+ {
+ s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ;
+ }
+ OSErr err = NewThread(kCooperativeThread,
+ s_threadEntry,
+ (void*) thread ,
+ 0 ,
+ kNewSuspend ,
+ &m_result ,
+ &m_tid ) ;
+
+ if ( err != noErr )
+ {
+ wxLogSysError(_("Can't create thread"));
+ return FALSE;
+ }
+
+ if ( m_priority != WXTHREAD_DEFAULT_PRIORITY )
+ {
+ SetPriority(m_priority);
+ }
+
+ return TRUE;
+}
+
+bool wxThreadInternal::Suspend()
+{
+ OSErr err ;
+
+ ::ThreadBeginCritical();
+
+ if ( m_state != STATE_RUNNING )
+ {
+ ::ThreadEndCritical() ;
+ wxLogSysError(_("Can not suspend thread %x"), m_tid);
+ return FALSE;
+ }
+
+ m_state = STATE_PAUSED;
+
+ err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID);
+
+ return TRUE;
+}
+
+bool wxThreadInternal::Resume()
+{
+ ThreadID current ;
+ OSErr err ;
+ err = MacGetCurrentThread( ¤t ) ;
+
+ wxASSERT( err == noErr ) ;
+ wxASSERT( current != m_tid ) ;
+
+ ::ThreadBeginCritical();
+ if ( m_state != STATE_PAUSED && m_state != STATE_NEW )
+ {
+ ::ThreadEndCritical() ;
+ wxLogSysError(_("Can not resume thread %x"), m_tid);
+ return FALSE;
+
+ }
+ err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID);
+ wxASSERT( err == noErr ) ;
+
+ m_state = STATE_RUNNING;
+ ::ThreadEndCritical() ;
+ ::YieldToAnyThread() ;
+ return TRUE;
+}
+
+// static functions
+// ----------------
+wxThread *wxThread::This()
+{
+ wxMacStCritical critical ;
+
+ ThreadID current ;
+ OSErr err ;
+
+ err = MacGetCurrentThread( ¤t ) ;
+
+ for ( int i = 0 ; i < s_threads.Count() ; ++i )
+ {
+ if ( ( (wxThread*) s_threads[i] )->GetId() == current )
+ return (wxThread*) s_threads[i] ;
+ }
+
+ wxLogSysError(_("Couldn't get the current thread pointer"));
+ return NULL;
+}
+
+bool wxThread::IsMain()
+{
+ ThreadID current ;
+ OSErr err ;
+
+ err = MacGetCurrentThread( ¤t ) ;
+ return current == gs_idMainThread;
+}
+
+#ifdef Yield
+#undef Yield
+#endif
+
+void wxThread::Yield()
+{
+ ::YieldToAnyThread() ;
+}
+
+void wxThread::Sleep(unsigned long milliseconds)
+{
+ clock_t start = clock() ;
+ do
+ {
+ YieldToAnyThread() ;
+ } while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ;
+}
+
+int wxThread::GetCPUCount()
+{
+ // we will use whatever MP API will be used for the new MP Macs
+ return 1;
+}
+
+bool wxThread::SetConcurrency(size_t level)
+{
+ wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
+
+ // ok only for the default one
+ if ( level == 0 )
+ return 0;
+
+ // how many CPUs have we got?
+ if ( GetCPUCount() == 1 )
+ {
+ // don't bother with all this complicated stuff - on a single
+ // processor system it doesn't make much sense anyhow
+ return level == 1;
+ }
+
+ return TRUE ;
+}
+
+// ctor and dtor
+// -------------
+
+wxThread::wxThread(wxThreadKind kind)
+{
+ m_internal = new wxThreadInternal();
+
+ m_isDetached = kind == wxTHREAD_DETACHED;
+ s_threads.Add( (void*) this ) ;
+}
+
+wxThread::~wxThread()
+{
+ s_threads.Remove( (void*) this ) ;
+ delete m_internal;
+}
+
+// create/start thread
+// -------------------
+