From b89156b5dbb3c1270452379801a79613cd69bb32 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Sun, 14 Jun 1998 15:28:28 +0000 Subject: [PATCH] * Thread updates and cleanup (m_locked, MUTEX_UNLOCKED added) * Updated the documentation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@94 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/mutex.tex | 7 +++--- include/wx/thread.h | 3 ++- src/gtk/threadgui.inc | 4 ++-- src/gtk/threadno.cpp | 49 +++++++++++++++++++++++------------------ src/gtk/threadpsx.cpp | 18 +++++++++------ src/gtk/threadsgi.cpp | 34 ++++++++++++++++++---------- src/gtk1/threadgui.inc | 4 ++-- src/gtk1/threadno.cpp | 49 +++++++++++++++++++++++------------------ src/gtk1/threadpsx.cpp | 18 +++++++++------ src/gtk1/threadsgi.cpp | 34 ++++++++++++++++++---------- src/msw/thread.cpp | 2 ++ 11 files changed, 134 insertions(+), 88 deletions(-) diff --git a/docs/latex/wx/mutex.tex b/docs/latex/wx/mutex.tex index 5009f0b60b..9b992c4509 100644 --- a/docs/latex/wx/mutex.tex +++ b/docs/latex/wx/mutex.tex @@ -45,7 +45,7 @@ One of: \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} @@ -62,7 +62,7 @@ One of: \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} @@ -79,7 +79,8 @@ One of: \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} diff --git a/include/wx/thread.h b/include/wx/thread.h index 08e462a442..64481d7c88 100644 --- a/include/wx/thread.h +++ b/include/wx/thread.h @@ -22,7 +22,8 @@ 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 { diff --git a/src/gtk/threadgui.inc b/src/gtk/threadgui.inc index 8195b0ddbd..165fef3c01 100644 --- a/src/gtk/threadgui.inc +++ b/src/gtk/threadgui.inc @@ -49,7 +49,7 @@ ThreadExitProc(gpointer WXUNUSED(client), gint fid, } // 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, @@ -57,7 +57,7 @@ static void wxThreadGuiInit(void) } // Global cleanup -static void wxThreadGuiExit(void) +static void wxThreadGuiExit() { gdk_input_remove(p_thrd_inid); close(p_thrd_pipe[0]); diff --git a/src/gtk/threadno.cpp b/src/gtk/threadno.cpp index 9b1686c349..126a211fca 100644 --- a/src/gtk/threadno.cpp +++ b/src/gtk/threadno.cpp @@ -16,29 +16,35 @@ 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() @@ -76,12 +82,12 @@ ThreadError wxThread::Create() { p_internal->exit_status = Entry(); OnExit(); - return NO_ERROR; + return THREAD_NO_ERROR; } ThreadError wxThread::Destroy() { - return RUNNING; + return THREAD_RUNNING; } void wxThread::DeferDestroy() @@ -135,22 +141,23 @@ void wxThread::OnExit() 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) diff --git a/src/gtk/threadpsx.cpp b/src/gtk/threadpsx.cpp index ce5396c6d7..07b5103654 100644 --- a/src/gtk/threadpsx.cpp +++ b/src/gtk/threadpsx.cpp @@ -51,13 +51,15 @@ wxMutex::wxMutex() { 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; } @@ -67,9 +69,8 @@ wxMutexError wxMutex::Lock() 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; } @@ -90,7 +91,10 @@ wxMutexError wxMutex::TryLock() 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; } diff --git a/src/gtk/threadsgi.cpp b/src/gtk/threadsgi.cpp index 575349e961..ea652677e1 100644 --- a/src/gtk/threadsgi.cpp +++ b/src/gtk/threadsgi.cpp @@ -46,34 +46,44 @@ public: 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() {} @@ -116,16 +126,16 @@ void wxThread::Exit(void* status) _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() diff --git a/src/gtk1/threadgui.inc b/src/gtk1/threadgui.inc index 8195b0ddbd..165fef3c01 100644 --- a/src/gtk1/threadgui.inc +++ b/src/gtk1/threadgui.inc @@ -49,7 +49,7 @@ ThreadExitProc(gpointer WXUNUSED(client), gint fid, } // 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, @@ -57,7 +57,7 @@ static void wxThreadGuiInit(void) } // Global cleanup -static void wxThreadGuiExit(void) +static void wxThreadGuiExit() { gdk_input_remove(p_thrd_inid); close(p_thrd_pipe[0]); diff --git a/src/gtk1/threadno.cpp b/src/gtk1/threadno.cpp index 9b1686c349..126a211fca 100644 --- a/src/gtk1/threadno.cpp +++ b/src/gtk1/threadno.cpp @@ -16,29 +16,35 @@ 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() @@ -76,12 +82,12 @@ ThreadError wxThread::Create() { p_internal->exit_status = Entry(); OnExit(); - return NO_ERROR; + return THREAD_NO_ERROR; } ThreadError wxThread::Destroy() { - return RUNNING; + return THREAD_RUNNING; } void wxThread::DeferDestroy() @@ -135,22 +141,23 @@ void wxThread::OnExit() 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) diff --git a/src/gtk1/threadpsx.cpp b/src/gtk1/threadpsx.cpp index ce5396c6d7..07b5103654 100644 --- a/src/gtk1/threadpsx.cpp +++ b/src/gtk1/threadpsx.cpp @@ -51,13 +51,15 @@ wxMutex::wxMutex() { 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; } @@ -67,9 +69,8 @@ wxMutexError wxMutex::Lock() 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; } @@ -90,7 +91,10 @@ wxMutexError wxMutex::TryLock() 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; } diff --git a/src/gtk1/threadsgi.cpp b/src/gtk1/threadsgi.cpp index 575349e961..ea652677e1 100644 --- a/src/gtk1/threadsgi.cpp +++ b/src/gtk1/threadsgi.cpp @@ -46,34 +46,44 @@ public: 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() {} @@ -116,16 +126,16 @@ void wxThread::Exit(void* status) _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() diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 86bbcfea6f..33ca0a645a 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -61,6 +61,8 @@ wxMutex::wxMutex() wxMutex::~wxMutex() { + if (m_locked > 0) + wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked); CloseHandle(p_internal->p_mutex); } -- 2.45.2