wxMutex::wxMutex()
{
p_internal = new wxMutexInternal;
+
pthread_mutex_init( &(p_internal->p_mutex), (const pthread_mutexattr_t*) NULL );
m_locked = 0;
}
// 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();
// wait until the thread stops
p_internal->Wait();
}
+ //GL: As we must auto-destroy, the destruction must happen here.
+ delete this;
return NULL;
}
return wxTHREAD_MISC_ERROR;
}
+ //GL: As we must auto-destroy, the destruction must happen here (2).
+ delete this;
return wxTHREAD_NO_ERROR;
}
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);
}
for ( size_t n = 0u; n < count; n++ )
{
- gs_allThreads[n]->Delete();
+ // Delete calls the destructor which removes the current entry. We
+ // should only delete the first one each time.
+ gs_allThreads[0]->Delete();
}
// destroy GUI mutex