bool wxThreadModule::OnInit() { bool hasThreadManager = #ifdef __LP64__ true ; // TODO VERIFY IN NEXT BUILD #else MPLibraryIsLoaded(); #endif if ( !hasThreadManager ) { wxLogError( wxT("MP thread support is not available on this system" ) ) ; return false; } // main thread's This() is NULL verify_noerr( MPAllocateTaskStorageIndex( &gs_tlsForWXThread ) ) ; verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread, 0 ) ) ; wxThread::ms_idMainThread = wxThread::GetCurrentId(); gs_critsectWaitingForGui = new wxCriticalSection(); gs_critsectGui = new wxCriticalSection(); gs_critsectGui->Enter(); return true; }
OSStatus wxThreadInternal::MacThreadStart(void *parameter) { wxThread* thread = (wxThread*) parameter ; wxThreadInternal *pthread = thread->m_internal; // add to TLS so that This() will work verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , (TaskStorageValue) thread ) ) ; // have to declare this before pthread_cleanup_push() which defines a // block! bool dontRunAtAll; // wait for the semaphore to be posted from Run() pthread->m_semRun.Wait(); // test whether we should run the run at all - may be it was deleted // before it started to Run()? { wxCriticalSectionLocker lock(thread->m_critsect); dontRunAtAll = pthread->GetState() == STATE_NEW && pthread->WasCancelled(); } if ( !dontRunAtAll ) { pthread->m_exitcode = thread->CallEntry(); { wxCriticalSectionLocker lock(thread->m_critsect); pthread->SetState( STATE_EXITED ); } } if ( dontRunAtAll ) { if ( pthread->m_isDetached ) delete thread; return -1; } else { // on Mac for the running code, // the correct thread termination is to return // terminate the thread thread->Exit( pthread->m_exitcode ); return (OSStatus) NULL; // pthread->m_exitcode; } }
void MacThreadLocalImpl::set(void* value) { MPSetTaskStorageValue(mTaskIndex, value); }