+public:
+ wxThreadInternal()
+ {
+ m_tid = kNoThreadID ;
+ m_state = STATE_NEW;
+ m_priority = WXTHREAD_DEFAULT_PRIORITY;
+ }
+
+ ~wxThreadInternal()
+ {
+ }
+
+ void Free()
+ {
+ }
+
+ // create a new (suspended) thread (for the given thread object)
+ bool Create(wxThread *thread, unsigned int stackSize);
+
+ // suspend/resume/terminate
+ bool Suspend();
+ bool Resume();
+ void Cancel() { m_state = STATE_CANCELED; }
+
+ // thread state
+ void SetState(wxThreadState state) { m_state = state; }
+ wxThreadState GetState() const { return m_state; }
+
+ // thread priority
+ void SetPriority(unsigned int priority);
+ unsigned int GetPriority() const { return m_priority; }
+
+ void SetResult( void *res ) { m_result = res ; }
+ void *GetResult() { return m_result ; }
+
+ // thread handle and id
+ ThreadID GetId() const { return m_tid; }
+
+ // thread function
+ static pascal void* MacThreadStart(wxThread* arg);
+
+private:
+ wxThreadState m_state; // state, see wxThreadState enum
+ unsigned int m_priority; // thread priority in "wx" units
+ ThreadID m_tid; // thread id
+ void* m_result;
+ static ThreadEntryUPP s_threadEntry ;
+};
+
+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, unsigned int stackSize)
+{
+ if ( s_threadEntry == NULL )
+ {
+ s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ;
+ }
+ OSErr err = NewThread( kCooperativeThread,
+ s_threadEntry,
+ (void*) thread,
+ stackSize,
+ 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;