X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/58230fb1b3d5e32f4199e473bb429216349068db..d8f2439cebed3b4b30c8978ecd2c2ffbb5d645c8:/src/unix/threadpsx.cpp diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index 50e99df2a7..ca1c7731b6 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -47,6 +47,10 @@ #include #endif +#ifdef __WXGTK12__ +#include "gtk/gtk.h" +#endif + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -81,8 +85,10 @@ static pthread_t gs_tidMain; // the key for the pointer to the associated wxThread object static pthread_key_t gs_keySelf; +#ifndef __WXGTK12__ // this mutex must be acquired before any call to a GUI function static wxMutex *gs_mutexGui; +#endif // ============================================================================ // implementation @@ -108,7 +114,7 @@ wxMutex::wxMutex() wxMutex::~wxMutex() { if (m_locked > 0) - wxLogDebug("Freeing a locked mutex (%d locks)", m_locked); + wxLogDebug(_T("Freeing a locked mutex (%d locks)"), m_locked); pthread_mutex_destroy( &(p_internal->p_mutex) ); delete p_internal; @@ -119,7 +125,7 @@ wxMutexError wxMutex::Lock() int err = pthread_mutex_lock( &(p_internal->p_mutex) ); if (err == EDEADLK) { - wxLogDebug("Locking this mutex would lead to deadlock!"); + wxLogDebug(_T("Locking this mutex would lead to deadlock!")); return wxMUTEX_DEAD_LOCK; } @@ -155,7 +161,7 @@ wxMutexError wxMutex::Unlock() } else { - wxLogDebug("Unlocking not locked mutex."); + wxLogDebug(_T("Unlocking not locked mutex.")); return wxMUTEX_UNLOCKED; } @@ -304,7 +310,7 @@ void *wxThreadInternal::PthreadStart(void *ptr) // terminate the thread thread->Exit(status); - wxFAIL_MSG("wxThread::Exit() can't return."); + wxFAIL_MSG(_T("wxThread::Exit() can't return.")); return NULL; } @@ -325,7 +331,8 @@ wxThreadInternal::wxThreadInternal() wxThreadInternal::~wxThreadInternal() { - m_mutexSuspend.Unlock(); + // GL: moved to SignalExit + // m_mutexSuspend.Unlock(); // note that m_mutex will be unlocked by the thread which waits for our // termination @@ -334,7 +341,7 @@ wxThreadInternal::~wxThreadInternal() wxThreadError wxThreadInternal::Run() { wxCHECK_MSG( GetState() == STATE_NEW, wxTHREAD_RUNNING, - "thread may only be started once after successful Create()" ); + _T("thread may only be started once after successful Create()") ); // the mutex was locked on Create(), so we will be able to lock it again // only when the thread really starts executing and enters the wait - @@ -353,7 +360,7 @@ wxThreadError wxThreadInternal::Run() void wxThreadInternal::Wait() { - wxCHECK_RET( WasCancelled(), "thread should have been cancelled first" ); + wxCHECK_RET( WasCancelled(), _T("thread should have been cancelled first") ); // if the thread we're waiting for is waiting for the GUI mutex, we will // deadlock so make sure we release it temporarily @@ -375,6 +382,9 @@ void wxThreadInternal::Wait() void wxThreadInternal::SignalExit() { + // GL: Unlock mutexSuspend here. + m_mutexSuspend.Unlock(); + // as mutex is currently locked, this will block until some other thread // (normally the same which created this one) unlocks it by entering Wait() m_mutex.Lock(); @@ -391,7 +401,7 @@ void wxThreadInternal::Pause() // the state is set from the thread which pauses us first, this function // is called later so the state should have been already set wxCHECK_RET( m_state == STATE_PAUSED, - "thread must first be paused with wxThread::Pause()." ); + _T("thread must first be paused with wxThread::Pause().") ); // don't pause the thread which is being terminated - this would lead to // deadlock if the thread is paused after Delete() had called Resume() but @@ -406,7 +416,7 @@ void wxThreadInternal::Pause() void wxThreadInternal::Resume() { wxCHECK_RET( m_state == STATE_PAUSED, - "can't resume thread which is not suspended." ); + _T("can't resume thread which is not suspended.") ); // we will be able to lock this mutex only when Pause() starts waiting wxMutexLocker lock(m_mutexSuspend); @@ -517,7 +527,7 @@ void wxThread::SetPriority(unsigned int prio) { wxCHECK_RET( ((int)WXTHREAD_MIN_PRIORITY <= (int)prio) && ((int)prio <= (int)WXTHREAD_MAX_PRIORITY), - "invalid thread priority" ); + _T("invalid thread priority") ); wxCriticalSectionLocker lock(m_critsect); @@ -546,7 +556,7 @@ void wxThread::SetPriority(unsigned int prio) case STATE_EXITED: default: - wxFAIL_MSG("impossible to set thread priority in this state"); + wxFAIL_MSG(_T("impossible to set thread priority in this state")); } } @@ -572,7 +582,7 @@ wxThreadError wxThread::Pause() if ( p_internal->GetState() != STATE_RUNNING ) { - wxLogDebug("Can't pause thread which is not running."); + wxLogDebug(_T("Can't pause thread which is not running.")); return wxTHREAD_NOT_RUNNING; } @@ -588,13 +598,15 @@ wxThreadError wxThread::Resume() if ( p_internal->GetState() == STATE_PAUSED ) { + m_critsect.Leave(); p_internal->Resume(); + m_critsect.Enter(); return wxTHREAD_NO_ERROR; } else { - wxLogDebug("Attempt to resume a thread which is not paused."); + wxLogDebug(_T("Attempt to resume a thread which is not paused.")); return wxTHREAD_MISC_ERROR; } @@ -663,12 +675,13 @@ void wxThread::Exit(void *status) // next wake up the threads waiting for us (OTOH, this function won't return // until someone waited for us!) - p_internal->SignalExit(); - p_internal->SetState(STATE_EXITED); + p_internal->SignalExit(); + // delete both C++ thread object and terminate the OS thread object - delete this; + // GL: This is very ugly and buggy ... +// delete this; pthread_exit(status); } @@ -724,6 +737,13 @@ bool wxThread::IsAlive() const } } +bool wxThread::IsPaused() const +{ + wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect); + + return (p_internal->GetState() == STATE_PAUSED); +} + //-------------------------------------------------------------------- // wxThreadModule //-------------------------------------------------------------------- @@ -751,36 +771,39 @@ bool wxThreadModule::OnInit() return FALSE; } +#ifndef __WXGTK12__ gs_mutexGui = new wxMutex(); - - //wxThreadGuiInit(); +#endif gs_tidMain = pthread_self(); + +#ifndef __WXGTK12__ gs_mutexGui->Lock(); +#endif return TRUE; } void wxThreadModule::OnExit() { - wxASSERT_MSG( wxThread::IsMain(), "only main thread can be here" ); + wxASSERT_MSG( wxThread::IsMain(), _T("only main thread can be here") ); // terminate any threads left size_t count = gs_allThreads.GetCount(); if ( count != 0u ) - wxLogDebug("Some threads were not terminated by the application."); + wxLogDebug(_T("Some threads were not terminated by the application.")); for ( size_t n = 0u; n < count; n++ ) { gs_allThreads[n]->Delete(); } +#ifndef __WXGTK12__ // destroy GUI mutex gs_mutexGui->Unlock(); - //wxThreadGuiExit(); - delete gs_mutexGui; +#endif // and free TLD slot (void)pthread_key_delete(gs_keySelf); @@ -792,12 +815,20 @@ void wxThreadModule::OnExit() void wxMutexGuiEnter() { +#ifdef __WXGTK12__ + gdk_threads_enter(); +#else gs_mutexGui->Lock(); +#endif } void wxMutexGuiLeave() { +#ifdef __WXGTK12__ + gdk_threads_leave(); +#else gs_mutexGui->Unlock(); +#endif } #endif