#include <sched.h>
#endif
-#ifdef __WXGTK12__
-#include "gtk/gtk.h"
-#endif
-
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// 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
// 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);
}
return FALSE;
}
-#ifndef __WXGTK12__
gs_mutexGui = new wxMutex();
-#endif
gs_tidMain = pthread_self();
-#ifndef __WXGTK12__
gs_mutexGui->Lock();
-#endif
return TRUE;
}
gs_allThreads[n]->Delete();
}
-#ifndef __WXGTK12__
// destroy GUI mutex
gs_mutexGui->Unlock();
delete gs_mutexGui;
-#endif
// and free TLD slot
(void)pthread_key_delete(gs_keySelf);
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