📄 thread.cpp
字号:
return true;}bool wxThreadInternal::Resume(){ ThreadID current ; OSErr err ; err = MacGetCurrentThread( ¤t ) ; wxASSERT( err == noErr ) ; wxASSERT( current != m_tid ) ; err = ::ThreadBeginCritical(); wxASSERT( err == noErr ) ; if ( m_state != STATE_PAUSED && m_state != STATE_NEW ) { err = ::ThreadEndCritical() ; wxASSERT( err == noErr ) ; wxLogSysError(_("Can not resume thread %x"), m_tid); return false; } err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID); m_state = STATE_RUNNING; err = ::ThreadEndCritical() ; wxASSERT( err == noErr ) ; ::YieldToAnyThread() ; return true;}// static functions// ----------------wxThread *wxThread::This(){ wxMacStCritical critical ; ThreadID current ; OSErr err ; err = MacGetCurrentThread( ¤t ) ; for ( size_t 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#endifvoid wxThread::Yield(){ ::YieldToAnyThread() ;}void wxThread::Sleep(unsigned long milliseconds){ UnsignedWide start, now; Microseconds(&start); double mssleep = milliseconds * 1000 ; double msstart, msnow ; msstart = (start.hi * 4294967296.0 + start.lo) ; do { YieldToAnyThread(); Microseconds(&now); msnow = (now.hi * 4294967296.0 + now.lo) ; } while( msnow - msstart < mssleep );}int wxThread::GetCPUCount(){ // we will use whatever MP API will be used for the new MP Macs return 1;}unsigned long wxThread::GetCurrentId(){ ThreadID current ; MacGetCurrentThread( ¤t ) ; return (unsigned long)current;}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){ g_numberOfThreads++; m_internal = new wxThreadInternal(); m_isDetached = kind == wxTHREAD_DETACHED; s_threads.Add( (void*) this ) ;}wxThread::~wxThread(){ if (g_numberOfThreads>0) { g_numberOfThreads--; }#ifdef __WXDEBUG__ else { wxFAIL_MSG(wxT("More threads deleted than created.")); }#endif s_threads.Remove( (void*) this ) ; if (m_internal != NULL) { delete m_internal; m_internal = NULL; }}// create/start thread// -------------------wxThreadError wxThread::Create(unsigned int stackSize){ wxCriticalSectionLocker lock(m_critsect); if ( !m_internal->Create(this, stackSize) ) return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_ERROR;}wxThreadError wxThread::Run(){ wxCriticalSectionLocker lock(m_critsect); if ( m_internal->GetState() != STATE_NEW ) { // actually, it may be almost any state at all, not only STATE_RUNNING return wxTHREAD_RUNNING; } // the thread has just been created and is still suspended - let it run return Resume();}// suspend/resume thread// ---------------------wxThreadError wxThread::Pause(){ wxCriticalSectionLocker lock(m_critsect); return m_internal->Suspend() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;}wxThreadError wxThread::Resume(){ wxCriticalSectionLocker lock(m_critsect); return m_internal->Resume() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;}// stopping thread// ---------------wxThread::ExitCode wxThread::Wait(){ // although under MacOS we can wait for any thread, it's an error to // wait for a detached one in wxWin API wxCHECK_MSG( !IsDetached(), (ExitCode)-1, _T("can't wait for detached thread") ); ExitCode rc = (ExitCode)-1; (void)Delete(&rc); m_internal->Free(); return rc;}wxThreadError wxThread::Delete(ExitCode *pRc){ ExitCode rc = 0; // Delete() is always safe to call, so consider all possible states // has the thread started to run? bool shouldResume = false; { wxCriticalSectionLocker lock(m_critsect); if ( m_internal->GetState() == STATE_NEW ) { // WinThreadStart() will see it and terminate immediately m_internal->SetState(STATE_EXITED); shouldResume = true; } } // is the thread paused? if ( shouldResume || IsPaused() ) Resume(); // does is still run? if ( IsRunning() ) { if ( IsMain() ) { // set flag for wxIsWaitingForThread() gs_waitingForThread = true;#if wxUSE_GUI wxBeginBusyCursor();#endif // wxUSE_GUI } // ask the thread to terminate { wxCriticalSectionLocker lock(m_critsect); m_internal->Cancel(); }#if wxUSE_GUI // simply wait for the thread to terminate while( TestDestroy() ) { ::YieldToAnyThread() ; }#else // !wxUSE_GUI // simply wait for the thread to terminate while( TestDestroy() ) { ::YieldToAnyThread() ; }#endif // wxUSE_GUI/!wxUSE_GUI if ( IsMain() ) { gs_waitingForThread = false;#if wxUSE_GUI wxEndBusyCursor();#endif // wxUSE_GUI } } if ( IsDetached() ) { // if the thread exits normally, this is done in WinThreadStart, but in // this case it would have been too early because // MsgWaitForMultipleObject() would fail if the therad handle was // closed while we were waiting on it, so we must do it here delete this; } if ( pRc ) *pRc = rc; return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR;}wxThreadError wxThread::Kill(){ if ( !IsRunning() ) return wxTHREAD_NOT_RUNNING;// if ( !::TerminateThread(m_internal->GetHandle(), (DWORD)-1) ) { wxLogSysError(_("Couldn't terminate thread")); return wxTHREAD_MISC_ERROR; } m_internal->Free(); if ( IsDetached() ) { delete this; } return wxTHREAD_NO_ERROR;}void wxThread::Exit(ExitCode status){ m_internal->Free(); if ( IsDetached() ) { delete this; } m_internal->SetResult( status ) ;/*#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) _endthreadex((unsigned)status);#else // !VC++ ::ExitThread((DWORD)status);#endif // VC++/!VC++*/ wxFAIL_MSG(wxT("Couldn't return from ExitThread()!"));}// priority setting// ----------------// since all these calls are execute cooperatively we don't have to use the critical sectionvoid wxThread::SetPriority(unsigned int prio){ m_internal->SetPriority(prio);}unsigned int wxThread::GetPriority() const{ return m_internal->GetPriority();}unsigned long wxThread::GetId() const{ return (unsigned long)m_internal->GetId();}bool wxThread::IsRunning() const{ return m_internal->GetState() == STATE_RUNNING;}bool wxThread::IsAlive() const{ return (m_internal->GetState() == STATE_RUNNING) || (m_internal->GetState() == STATE_PAUSED);}bool wxThread::IsPaused() const{ return m_internal->GetState() == STATE_PAUSED;}bool wxThread::TestDestroy(){ return m_internal->GetState() == STATE_CANCELED;}// ----------------------------------------------------------------------------// Automatic initialization for thread module// ----------------------------------------------------------------------------class wxThreadModule : public wxModule{public: virtual bool OnInit(); virtual void OnExit();private: DECLARE_DYNAMIC_CLASS(wxThreadModule)};IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)bool wxThreadModule::OnInit(){ long response; bool hasThreadManager ; hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1;#if !TARGET_CARBON#if GENERATINGCFM // verify presence of shared library hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress);#endif#endif if ( !hasThreadManager ) { wxLogSysError( wxT("Thread Support is not available on this System") ); return false ; } // no error return for GetCurrentThreadId() MacGetCurrentThread( &gs_idMainThread ) ; return true;}void wxThreadModule::OnExit(){}// ----------------------------------------------------------------------------// under MacOS we don't have currently preemptive threads, so any thread may access// the GUI at any time// ----------------------------------------------------------------------------void WXDLLEXPORT wxMutexGuiEnter(){}void WXDLLEXPORT wxMutexGuiLeave(){}void WXDLLEXPORT wxMutexGuiLeaveOrEnter(){}bool WXDLLEXPORT wxGuiOwnedByMainThread(){ return false ;}// wake up the main threadvoid WXDLLEXPORT wxWakeUpMainThread(){ wxMacWakeUp() ;}bool WXDLLEXPORT wxIsWaitingForThread(){ return false ;}#include "wx/thrimpl.cpp"#endif // wxUSE_THREADS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -