\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
-\twocolitem{{\bf MUTEX\_BUSY}}{The thread is already running.}
+\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.}
\end{twocollist}
\membersection{wxMutex::TryLock}\label{wxmutextrylock}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
-\twocolitem{{\bf MUTEX\_BUSY}}{The thread is already running.}
+\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.}
\end{twocollist}
\membersection{wxMutex::Unlock}\label{wxmutexunlock}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
-\twocolitem{{\bf MUTEX\_BUSY}}{The thread is already running.}
+\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.}
+\twocolitem{{\bf MUTEX\_UNLOCKED}}{The calling thread tries to unlock an unlocked mutex.}
\end{twocollist}
typedef enum {
MUTEX_NO_ERROR=0,
MUTEX_DEAD_LOCK, // Mutex has been already locked by THE CALLING thread
- MUTEX_BUSY // Mutex has been already locked by ONE thread
+ MUTEX_BUSY, // Mutex has been already locked by ONE thread
+ MUTEX_UNLOCKED
} wxMutexError;
typedef enum {
}
// Global initialization
-static void wxThreadGuiInit(void)
+static void wxThreadGuiInit()
{
pipe(p_thrd_pipe);
p_thrd_inid = gdk_input_add(p_thrd_pipe[0], GDK_INPUT_READ,
}
// Global cleanup
-static void wxThreadGuiExit(void)
+static void wxThreadGuiExit()
{
gdk_input_remove(p_thrd_inid);
close(p_thrd_pipe[0]);
wxMutex::wxMutex()
{
- m_locked = FALSE;
+ m_locked = 0;
}
wxMutex::~wxMutex()
{
+ if (m_locked)
+ wxDebugMsg("wxMutex warning: destroying a locked mutex (%d locks)\n", m_locked);
}
MutexError wxMutex::Lock()
{
- m_locked = TRUE;
- return NO_ERROR;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
MutexError wxMutex::TryLock()
{
- m_locked = TRUE;
- return NO_ERROR;
+ if (m_locked > 0)
+ return MUTEX_BUSY;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
MutexError wxMutex::Unlock()
{
- m_locked = FALSE;
- return NO_ERROR;
+ if (m_locked == 0)
+ return MUTEX_UNLOCKED;
+ m_locked--;
+ return MUTEX_NO_ERROR;
}
wxCondition::wxCondition()
{
p_internal->exit_status = Entry();
OnExit();
- return NO_ERROR;
+ return THREAD_NO_ERROR;
}
ThreadError wxThread::Destroy()
{
- return RUNNING;
+ return THREAD_RUNNING;
}
void wxThread::DeferDestroy()
Join();
}
-// Global initialization
-static void wxThreadInit(void *WXUNUSED(client))
-{
+
+// Automatic initialization
+class wxThreadModule : public wxModule {
+ DECLARE_DYNAMIC_CLASS(wxThreadModule)
+public:
+ bool OnInit();
+ void OnExit();
+};
+
+bool wxThreadModule::OnInit() {
wxMainMutex.Lock();
+ return TRUE;
}
-// Global cleanup
-static void wxThreadExit(void *WXUNUSED(client))
+void wxThreadModule::wxThreadExit()
{
wxMainMutex.Unlock();
}
-// Let automatic initialization be performed from wxCommonInit().
-static struct
-wxThreadGlobal {
- wxThreadGlobal() {
- wxRegisterModuleFunction(wxThreadInit, wxThreadExit, NULL);
- }
-} dummy;
+IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
{
p_internal = new wxMutexInternal;
pthread_mutex_init(&(p_internal->p_mutex), NULL);
- m_locked = false;
+ m_locked = 0;
}
wxMutex::~wxMutex()
{
- if (m_locked)
- pthread_mutex_unlock(&(p_internal->p_mutex));
+ if (m_locked > 0)
+ wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n",
+ m_locked);
+
pthread_mutex_destroy(&(p_internal->p_mutex));
delete p_internal;
}
int err;
err = pthread_mutex_lock(&(p_internal->p_mutex));
- switch (err) {
- case EDEADLK: return MUTEX_DEAD_LOCK;
- }
+ if (err == EDEADLK)
+ return MUTEX_DEAD_LOCK;
m_locked++;
return MUTEX_NO_ERROR;
}
wxMutexError wxMutex::Unlock()
{
- if (m_locked > 0) m_locked--;
+ if (m_locked > 0)
+ m_locked--;
+ else
+ return MUTEX_UNLOCKED;
pthread_mutex_unlock(&(p_internal->p_mutex));
return MUTEX_NO_ERROR;
}
wxMutex::wxMutex()
{
+ m_locked = 0;
p_internal = new wxMutexInternal;
init_lock(&(p_internal->p_mutex));
}
wxMutex::~wxMutex()
{
+ if (m_locked > 0)
+ wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n",
+ m_locked);
+ delete p_internal;
}
-wxMutex::MutexError wxMutex::Lock()
+wxMutexError wxMutex::Lock()
{
spin_lock(&(p_internal->p_mutex));
- return NO_ERROR;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
-wxMutex::MutexError wxMutex::TryLock()
+wxMutexError wxMutex::TryLock()
{
if (acquire_lock(&(p_internal->p_mutex)) != 0)
- return BUSY;
- return NO_ERROR;
+ return MUTEX_BUSY;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
-wxMutex::MutexError wxMutex::Unlock()
+wxMutexError wxMutex::Unlock()
{
+ if (m_locked == 0)
+ return MUTEX_UNLOCKED;
release_lock(&(p_internal->p_mutex));
- return NO_ERROR;
+ m_locked--;
+ return MUTEX_NO_ERROR;
}
-// GLH: Don't now how it works on SGI. Wolfram ?
+// GL: Don't know how it works on SGI. Wolfram ?
wxCondition::wxCondition() {}
wxCondition::~wxCondition() {}
_exit(0);
}
-wxThread::ThreadError wxThread::Create()
+wxThreadError wxThread::Create()
{
if (p_internal->state != STATE_IDLE)
- return RUNNING;
+ return THREAD_RUNNING;
p_internal->state = STATE_RUNNING;
if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
p_internal->state = STATE_IDLE;
- return NO_RESOURCE;
+ return THREAD_NO_RESOURCE;
}
- return NO_ERROR;
+ return THREAD_NO_ERROR;
}
void wxThread::Destroy()
}
// Global initialization
-static void wxThreadGuiInit(void)
+static void wxThreadGuiInit()
{
pipe(p_thrd_pipe);
p_thrd_inid = gdk_input_add(p_thrd_pipe[0], GDK_INPUT_READ,
}
// Global cleanup
-static void wxThreadGuiExit(void)
+static void wxThreadGuiExit()
{
gdk_input_remove(p_thrd_inid);
close(p_thrd_pipe[0]);
wxMutex::wxMutex()
{
- m_locked = FALSE;
+ m_locked = 0;
}
wxMutex::~wxMutex()
{
+ if (m_locked)
+ wxDebugMsg("wxMutex warning: destroying a locked mutex (%d locks)\n", m_locked);
}
MutexError wxMutex::Lock()
{
- m_locked = TRUE;
- return NO_ERROR;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
MutexError wxMutex::TryLock()
{
- m_locked = TRUE;
- return NO_ERROR;
+ if (m_locked > 0)
+ return MUTEX_BUSY;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
MutexError wxMutex::Unlock()
{
- m_locked = FALSE;
- return NO_ERROR;
+ if (m_locked == 0)
+ return MUTEX_UNLOCKED;
+ m_locked--;
+ return MUTEX_NO_ERROR;
}
wxCondition::wxCondition()
{
p_internal->exit_status = Entry();
OnExit();
- return NO_ERROR;
+ return THREAD_NO_ERROR;
}
ThreadError wxThread::Destroy()
{
- return RUNNING;
+ return THREAD_RUNNING;
}
void wxThread::DeferDestroy()
Join();
}
-// Global initialization
-static void wxThreadInit(void *WXUNUSED(client))
-{
+
+// Automatic initialization
+class wxThreadModule : public wxModule {
+ DECLARE_DYNAMIC_CLASS(wxThreadModule)
+public:
+ bool OnInit();
+ void OnExit();
+};
+
+bool wxThreadModule::OnInit() {
wxMainMutex.Lock();
+ return TRUE;
}
-// Global cleanup
-static void wxThreadExit(void *WXUNUSED(client))
+void wxThreadModule::wxThreadExit()
{
wxMainMutex.Unlock();
}
-// Let automatic initialization be performed from wxCommonInit().
-static struct
-wxThreadGlobal {
- wxThreadGlobal() {
- wxRegisterModuleFunction(wxThreadInit, wxThreadExit, NULL);
- }
-} dummy;
+IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
{
p_internal = new wxMutexInternal;
pthread_mutex_init(&(p_internal->p_mutex), NULL);
- m_locked = false;
+ m_locked = 0;
}
wxMutex::~wxMutex()
{
- if (m_locked)
- pthread_mutex_unlock(&(p_internal->p_mutex));
+ if (m_locked > 0)
+ wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n",
+ m_locked);
+
pthread_mutex_destroy(&(p_internal->p_mutex));
delete p_internal;
}
int err;
err = pthread_mutex_lock(&(p_internal->p_mutex));
- switch (err) {
- case EDEADLK: return MUTEX_DEAD_LOCK;
- }
+ if (err == EDEADLK)
+ return MUTEX_DEAD_LOCK;
m_locked++;
return MUTEX_NO_ERROR;
}
wxMutexError wxMutex::Unlock()
{
- if (m_locked > 0) m_locked--;
+ if (m_locked > 0)
+ m_locked--;
+ else
+ return MUTEX_UNLOCKED;
pthread_mutex_unlock(&(p_internal->p_mutex));
return MUTEX_NO_ERROR;
}
wxMutex::wxMutex()
{
+ m_locked = 0;
p_internal = new wxMutexInternal;
init_lock(&(p_internal->p_mutex));
}
wxMutex::~wxMutex()
{
+ if (m_locked > 0)
+ wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n",
+ m_locked);
+ delete p_internal;
}
-wxMutex::MutexError wxMutex::Lock()
+wxMutexError wxMutex::Lock()
{
spin_lock(&(p_internal->p_mutex));
- return NO_ERROR;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
-wxMutex::MutexError wxMutex::TryLock()
+wxMutexError wxMutex::TryLock()
{
if (acquire_lock(&(p_internal->p_mutex)) != 0)
- return BUSY;
- return NO_ERROR;
+ return MUTEX_BUSY;
+ m_locked++;
+ return MUTEX_NO_ERROR;
}
-wxMutex::MutexError wxMutex::Unlock()
+wxMutexError wxMutex::Unlock()
{
+ if (m_locked == 0)
+ return MUTEX_UNLOCKED;
release_lock(&(p_internal->p_mutex));
- return NO_ERROR;
+ m_locked--;
+ return MUTEX_NO_ERROR;
}
-// GLH: Don't now how it works on SGI. Wolfram ?
+// GL: Don't know how it works on SGI. Wolfram ?
wxCondition::wxCondition() {}
wxCondition::~wxCondition() {}
_exit(0);
}
-wxThread::ThreadError wxThread::Create()
+wxThreadError wxThread::Create()
{
if (p_internal->state != STATE_IDLE)
- return RUNNING;
+ return THREAD_RUNNING;
p_internal->state = STATE_RUNNING;
if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
p_internal->state = STATE_IDLE;
- return NO_RESOURCE;
+ return THREAD_NO_RESOURCE;
}
- return NO_ERROR;
+ return THREAD_NO_ERROR;
}
void wxThread::Destroy()
wxMutex::~wxMutex()
{
+ if (m_locked > 0)
+ wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked);
CloseHandle(p_internal->p_mutex);
}