X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/79b7b95aed76eb742deef93d046886c20452fb36..df344ba9df2d455286b67f9f03b6d7ea28bc61fa:/src/unix/threadpsx.cpp diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index 0384805c1a..2775f9576e 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -128,11 +128,11 @@ static pthread_key_t gs_keySelf; static size_t gs_nThreadsBeingDeleted = 0; // a mutex to protect gs_nThreadsBeingDeleted -static wxMutex *gs_mutexDeleteThread = (wxMutex *)NULL; +static wxMutex *gs_mutexDeleteThread = NULL; // and a condition variable which will be signaled when all // gs_nThreadsBeingDeleted will have been deleted -static wxCondition *gs_condAllDeleted = (wxCondition *)NULL; +static wxCondition *gs_condAllDeleted = NULL; // this mutex must be acquired before any call to a GUI function // (it's not inside #if wxUSE_GUI because this file is compiled as part @@ -178,6 +178,8 @@ private: private: pthread_mutex_t m_mutex; bool m_isOk; + wxMutexType m_type; + unsigned long m_owningThread; // wxConditionInternal uses our m_mutex friend class wxConditionInternal; @@ -192,6 +194,9 @@ extern "C" int pthread_mutexattr_settype(pthread_mutexattr_t *, int); wxMutexInternal::wxMutexInternal(wxMutexType mutexType) { + m_type = mutexType; + m_owningThread = 0; + int err; switch ( mutexType ) { @@ -252,6 +257,12 @@ wxMutexInternal::~wxMutexInternal() wxMutexError wxMutexInternal::Lock() { + if ((m_type == wxMUTEX_DEFAULT) && (m_owningThread != 0)) + { + if (m_owningThread == wxThread::GetCurrentId()) + return wxMUTEX_DEAD_LOCK; + } + return HandleLockResult(pthread_mutex_lock(&m_mutex)); } @@ -307,6 +318,8 @@ wxMutexError wxMutexInternal::Lock(unsigned long ms) wxMutexError wxMutexInternal::HandleLockResult(int err) { + // wxPrintf( "err %d\n", err ); + switch ( err ) { case EDEADLK: @@ -323,6 +336,8 @@ wxMutexError wxMutexInternal::HandleLockResult(int err) return wxMUTEX_TIMEOUT; case 0: + if (m_type == wxMUTEX_DEFAULT) + m_owningThread = wxThread::GetCurrentId(); return wxMUTEX_NO_ERROR; default: @@ -348,6 +363,8 @@ wxMutexError wxMutexInternal::TryLock() break; case 0: + if (m_type == wxMUTEX_DEFAULT) + m_owningThread = wxThread::GetCurrentId(); return wxMUTEX_NO_ERROR; default: @@ -359,6 +376,8 @@ wxMutexError wxMutexInternal::TryLock() wxMutexError wxMutexInternal::Unlock() { + m_owningThread = 0; + int err = pthread_mutex_unlock(&m_mutex); switch ( err ) { @@ -570,14 +589,14 @@ wxSemaError wxSemaphoreInternal::Wait() while ( m_count == 0 ) { wxLogTrace(TRACE_SEMA, - _T("Thread %ld waiting for semaphore to become signalled"), + _T("Thread %p waiting for semaphore to become signalled"), wxThread::GetCurrentId()); if ( m_cond.Wait() != wxCOND_NO_ERROR ) return wxSEMA_MISC_ERROR; wxLogTrace(TRACE_SEMA, - _T("Thread %ld finished waiting for semaphore, count = %lu"), + _T("Thread %p finished waiting for semaphore, count = %lu"), wxThread::GetCurrentId(), (unsigned long)m_count); } @@ -644,7 +663,7 @@ wxSemaError wxSemaphoreInternal::Post() m_count++; wxLogTrace(TRACE_SEMA, - _T("Thread %ld about to signal semaphore, count = %lu"), + _T("Thread %p about to signal semaphore, count = %lu"), wxThread::GetCurrentId(), (unsigned long)m_count); return m_cond.Signal() == wxCOND_NO_ERROR ? wxSEMA_NO_ERROR @@ -701,7 +720,7 @@ public: wxThreadState GetState() const { return m_state; } void SetState(wxThreadState state) { -#ifdef __WXDEBUG__ +#if wxUSE_LOG_TRACE static const wxChar *stateNames[] = { _T("NEW"), @@ -710,9 +729,9 @@ public: _T("EXITED"), }; - wxLogTrace(TRACE_THREADS, _T("Thread %ld: %s => %s."), - (long)GetId(), stateNames[m_state], stateNames[state]); -#endif // __WXDEBUG__ + wxLogTrace(TRACE_THREADS, _T("Thread %p: %s => %s."), + GetId(), stateNames[m_state], stateNames[state]); +#endif // wxUSE_LOG_TRACE m_state = state; } @@ -787,7 +806,7 @@ void *wxThreadInternal::PthreadStart(wxThread *thread) { wxThreadInternal *pthread = thread->m_internal; - wxLogTrace(TRACE_THREADS, _T("Thread %ld started."), THR_ID(pthread)); + wxLogTrace(TRACE_THREADS, _T("Thread %p started."), THR_ID(pthread)); // associate the thread pointer with the newly created thread so that // wxThread::This() will work @@ -825,7 +844,7 @@ void *wxThreadInternal::PthreadStart(wxThread *thread) { // call the main entry wxLogTrace(TRACE_THREADS, - _T("Thread %ld about to enter its Entry()."), + _T("Thread %p about to enter its Entry()."), THR_ID(pthread)); wxTRY @@ -833,7 +852,7 @@ void *wxThreadInternal::PthreadStart(wxThread *thread) pthread->m_exitcode = thread->Entry(); wxLogTrace(TRACE_THREADS, - _T("Thread %ld Entry() returned %lu."), + _T("Thread %p Entry() returned %lu."), THR_ID(pthread), wxPtrToUInt(pthread->m_exitcode)); } wxCATCH_ALL( wxTheApp->OnUnhandledException(); ) @@ -956,7 +975,7 @@ void wxThreadInternal::Wait() wxMutexGuiLeave(); wxLogTrace(TRACE_THREADS, - _T("Starting to wait for thread %ld to exit."), + _T("Starting to wait for thread %p to exit."), THR_ID(this)); // to avoid memory leaks we should call pthread_join(), but it must only be @@ -996,7 +1015,7 @@ void wxThreadInternal::Pause() wxT("thread must first be paused with wxThread::Pause().") ); wxLogTrace(TRACE_THREADS, - _T("Thread %ld goes to sleep."), THR_ID(this)); + _T("Thread %p goes to sleep."), THR_ID(this)); // wait until the semaphore is Post()ed from Resume() m_semSuspend.Wait(); @@ -1012,7 +1031,7 @@ void wxThreadInternal::Resume() if ( IsReallyPaused() ) { wxLogTrace(TRACE_THREADS, - _T("Waking up thread %ld"), THR_ID(this)); + _T("Waking up thread %p"), THR_ID(this)); // wake up Pause() m_semSuspend.Post(); @@ -1023,7 +1042,7 @@ void wxThreadInternal::Resume() else { wxLogTrace(TRACE_THREADS, - _T("Thread %ld is not yet really paused"), THR_ID(this)); + _T("Thread %p is not yet really paused"), THR_ID(this)); } SetState(STATE_RUNNING); @@ -1050,11 +1069,6 @@ void wxThread::Yield() #endif } -void wxThread::Sleep(unsigned long milliseconds) -{ - wxMilliSleep(milliseconds); -} - int wxThread::GetCPUCount() { #if defined(_SC_NPROCESSORS_ONLN) @@ -1391,7 +1405,7 @@ wxThreadError wxThread::Resume() switch ( state ) { case STATE_PAUSED: - wxLogTrace(TRACE_THREADS, _T("Thread %ld suspended, resuming."), + wxLogTrace(TRACE_THREADS, _T("Thread %p suspended, resuming."), GetId()); m_internal->Resume(); @@ -1399,7 +1413,7 @@ wxThreadError wxThread::Resume() return wxTHREAD_NO_ERROR; case STATE_EXITED: - wxLogTrace(TRACE_THREADS, _T("Thread %ld exited, won't resume."), + wxLogTrace(TRACE_THREADS, _T("Thread %p exited, won't resume."), GetId()); return wxTHREAD_NO_ERROR; @@ -1610,7 +1624,6 @@ bool wxThread::TestDestroy() wxThread::~wxThread() { -#ifdef __WXDEBUG__ m_critsect.Enter(); // check that the thread either exited or couldn't be created @@ -1622,7 +1635,6 @@ wxThread::~wxThread() } m_critsect.Leave(); -#endif // __WXDEBUG__ delete m_internal; @@ -1783,14 +1795,14 @@ static void DeleteThread(wxThread *This) // or wxThreadModule::OnExit() would deadlock wxMutexLocker locker( *gs_mutexDeleteThread ); - wxLogTrace(TRACE_THREADS, _T("Thread %ld auto deletes."), This->GetId()); + wxLogTrace(TRACE_THREADS, _T("Thread %p auto deletes."), This->GetId()); delete This; wxCHECK_RET( gs_nThreadsBeingDeleted > 0, _T("no threads scheduled for deletion, yet we delete one?") ); - wxLogTrace(TRACE_THREADS, _T("%lu scheduled for deletion threads left."), + wxLogTrace(TRACE_THREADS, _T("%lu threads remain scheduled for deletion."), (unsigned long)gs_nThreadsBeingDeleted - 1); if ( !--gs_nThreadsBeingDeleted ) @@ -1800,12 +1812,12 @@ static void DeleteThread(wxThread *This) } } -void wxMutexGuiEnter() +void wxMutexGuiEnterImpl() { gs_mutexGui->Lock(); } -void wxMutexGuiLeave() +void wxMutexGuiLeaveImpl() { gs_mutexGui->Unlock(); }