// state
// 2. The Delete() function blocks until the condition is signaled when the
// thread exits.
+ // GL: On Linux, this may fail because we can have a deadlock in either
+ // SignalExit() or Wait(): so we add m_end_mutex for the finalization.
wxMutex m_mutex, m_end_mutex;
wxCondition m_cond;
}
#if HAVE_THREAD_CLEANUP_FUNCTIONS
// Install the cleanup handler.
-// pthread_cleanup_push(wxThreadInternal::PthreadCleanup, ptr);
+ pthread_cleanup_push(wxThreadInternal::PthreadCleanup, ptr);
#endif
// wait for the condition to be signaled from Run()
status = thread->Entry();
#if HAVE_THREAD_CLEANUP_FUNCTIONS
-// pthread_cleanup_pop(FALSE);
+ pthread_cleanup_pop(FALSE);
#endif
// terminate the thread
// note that m_mutex will be unlocked by the thread which waits for our
// termination
- // m_end_mutex can be unlocked here.
- m_end_mutex.Unlock();
+ // In the case, we didn't start the thread, all these mutex are locked:
+ // we must unlock them.
+ if (m_mutex.IsLocked())
+ m_mutex.Unlock();
+
+ if (m_end_mutex.IsLocked())
+ m_end_mutex.Unlock();
+
+ if (m_mutexSuspend.IsLocked())
+ m_mutexSuspend.Unlock();
}
wxThreadError wxThreadInternal::Run()
wxThread::ExitCode wxThread::Delete()
{
+ if (IsPaused())
+ Resume();
+
m_critsect.Enter();
wxThreadState state = p_internal->GetState();
wxThread::~wxThread()
{
+ m_critsect.Enter();
+ if (p_internal->GetState() != STATE_EXITED &&
+ p_internal->GetState() != STATE_NEW)
+ wxLogDebug(_T("The thread is being destroyed althought it is still running ! The application may crash."));
+
+ m_critsect.Leave();
+
+ delete p_internal;
// remove this thread from the global array
gs_allThreads.Remove(this);
}