* 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
This commit is contained in:
Guilhem Lavaux
1998-06-14 15:28:28 +00:00
parent ee4f8c2af9
commit b89156b5db
11 changed files with 134 additions and 88 deletions

View File

@@ -45,7 +45,7 @@ One of:
\begin{twocollist}\itemsep=0pt \begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.} \twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} \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} \end{twocollist}
\membersection{wxMutex::TryLock}\label{wxmutextrylock} \membersection{wxMutex::TryLock}\label{wxmutextrylock}
@@ -62,7 +62,7 @@ One of:
\begin{twocollist}\itemsep=0pt \begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.} \twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} \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} \end{twocollist}
\membersection{wxMutex::Unlock}\label{wxmutexunlock} \membersection{wxMutex::Unlock}\label{wxmutexunlock}
@@ -79,7 +79,8 @@ One of:
\begin{twocollist}\itemsep=0pt \begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.} \twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.} \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} \end{twocollist}

View File

@@ -22,7 +22,8 @@
typedef enum { typedef enum {
MUTEX_NO_ERROR=0, MUTEX_NO_ERROR=0,
MUTEX_DEAD_LOCK, // Mutex has been already locked by THE CALLING thread 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; } wxMutexError;
typedef enum { typedef enum {

View File

@@ -49,7 +49,7 @@ ThreadExitProc(gpointer WXUNUSED(client), gint fid,
} }
// Global initialization // Global initialization
static void wxThreadGuiInit(void) static void wxThreadGuiInit()
{ {
pipe(p_thrd_pipe); pipe(p_thrd_pipe);
p_thrd_inid = gdk_input_add(p_thrd_pipe[0], GDK_INPUT_READ, p_thrd_inid = gdk_input_add(p_thrd_pipe[0], GDK_INPUT_READ,
@@ -57,7 +57,7 @@ static void wxThreadGuiInit(void)
} }
// Global cleanup // Global cleanup
static void wxThreadGuiExit(void) static void wxThreadGuiExit()
{ {
gdk_input_remove(p_thrd_inid); gdk_input_remove(p_thrd_inid);
close(p_thrd_pipe[0]); close(p_thrd_pipe[0]);

View File

@@ -16,29 +16,35 @@
wxMutex::wxMutex() wxMutex::wxMutex()
{ {
m_locked = FALSE; m_locked = 0;
} }
wxMutex::~wxMutex() wxMutex::~wxMutex()
{ {
if (m_locked)
wxDebugMsg("wxMutex warning: destroying a locked mutex (%d locks)\n", m_locked);
} }
MutexError wxMutex::Lock() MutexError wxMutex::Lock()
{ {
m_locked = TRUE; m_locked++;
return NO_ERROR; return MUTEX_NO_ERROR;
} }
MutexError wxMutex::TryLock() MutexError wxMutex::TryLock()
{ {
m_locked = TRUE; if (m_locked > 0)
return NO_ERROR; return MUTEX_BUSY;
m_locked++;
return MUTEX_NO_ERROR;
} }
MutexError wxMutex::Unlock() MutexError wxMutex::Unlock()
{ {
m_locked = FALSE; if (m_locked == 0)
return NO_ERROR; return MUTEX_UNLOCKED;
m_locked--;
return MUTEX_NO_ERROR;
} }
wxCondition::wxCondition() wxCondition::wxCondition()
@@ -76,12 +82,12 @@ ThreadError wxThread::Create()
{ {
p_internal->exit_status = Entry(); p_internal->exit_status = Entry();
OnExit(); OnExit();
return NO_ERROR; return THREAD_NO_ERROR;
} }
ThreadError wxThread::Destroy() ThreadError wxThread::Destroy()
{ {
return RUNNING; return THREAD_RUNNING;
} }
void wxThread::DeferDestroy() void wxThread::DeferDestroy()
@@ -135,22 +141,23 @@ void wxThread::OnExit()
Join(); 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(); wxMainMutex.Lock();
return TRUE;
} }
// Global cleanup void wxThreadModule::wxThreadExit()
static void wxThreadExit(void *WXUNUSED(client))
{ {
wxMainMutex.Unlock(); wxMainMutex.Unlock();
} }
// Let automatic initialization be performed from wxCommonInit(). IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
static struct
wxThreadGlobal {
wxThreadGlobal() {
wxRegisterModuleFunction(wxThreadInit, wxThreadExit, NULL);
}
} dummy;

View File

@@ -51,13 +51,15 @@ wxMutex::wxMutex()
{ {
p_internal = new wxMutexInternal; p_internal = new wxMutexInternal;
pthread_mutex_init(&(p_internal->p_mutex), NULL); pthread_mutex_init(&(p_internal->p_mutex), NULL);
m_locked = false; m_locked = 0;
} }
wxMutex::~wxMutex() wxMutex::~wxMutex()
{ {
if (m_locked) if (m_locked > 0)
pthread_mutex_unlock(&(p_internal->p_mutex)); wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n",
m_locked);
pthread_mutex_destroy(&(p_internal->p_mutex)); pthread_mutex_destroy(&(p_internal->p_mutex));
delete p_internal; delete p_internal;
} }
@@ -67,9 +69,8 @@ wxMutexError wxMutex::Lock()
int err; int err;
err = pthread_mutex_lock(&(p_internal->p_mutex)); err = pthread_mutex_lock(&(p_internal->p_mutex));
switch (err) { if (err == EDEADLK)
case EDEADLK: return MUTEX_DEAD_LOCK; return MUTEX_DEAD_LOCK;
}
m_locked++; m_locked++;
return MUTEX_NO_ERROR; return MUTEX_NO_ERROR;
} }
@@ -90,7 +91,10 @@ wxMutexError wxMutex::TryLock()
wxMutexError wxMutex::Unlock() 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)); pthread_mutex_unlock(&(p_internal->p_mutex));
return MUTEX_NO_ERROR; return MUTEX_NO_ERROR;
} }

View File

@@ -46,34 +46,44 @@ public:
wxMutex::wxMutex() wxMutex::wxMutex()
{ {
m_locked = 0;
p_internal = new wxMutexInternal; p_internal = new wxMutexInternal;
init_lock(&(p_internal->p_mutex)); init_lock(&(p_internal->p_mutex));
} }
wxMutex::~wxMutex() 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)); 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) if (acquire_lock(&(p_internal->p_mutex)) != 0)
return BUSY; return MUTEX_BUSY;
return NO_ERROR; 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)); 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() {}
wxCondition::~wxCondition() {} wxCondition::~wxCondition() {}
@@ -116,16 +126,16 @@ void wxThread::Exit(void* status)
_exit(0); _exit(0);
} }
wxThread::ThreadError wxThread::Create() wxThreadError wxThread::Create()
{ {
if (p_internal->state != STATE_IDLE) if (p_internal->state != STATE_IDLE)
return RUNNING; return THREAD_RUNNING;
p_internal->state = STATE_RUNNING; p_internal->state = STATE_RUNNING;
if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) { if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
p_internal->state = STATE_IDLE; p_internal->state = STATE_IDLE;
return NO_RESOURCE; return THREAD_NO_RESOURCE;
} }
return NO_ERROR; return THREAD_NO_ERROR;
} }
void wxThread::Destroy() void wxThread::Destroy()

View File

@@ -49,7 +49,7 @@ ThreadExitProc(gpointer WXUNUSED(client), gint fid,
} }
// Global initialization // Global initialization
static void wxThreadGuiInit(void) static void wxThreadGuiInit()
{ {
pipe(p_thrd_pipe); pipe(p_thrd_pipe);
p_thrd_inid = gdk_input_add(p_thrd_pipe[0], GDK_INPUT_READ, p_thrd_inid = gdk_input_add(p_thrd_pipe[0], GDK_INPUT_READ,
@@ -57,7 +57,7 @@ static void wxThreadGuiInit(void)
} }
// Global cleanup // Global cleanup
static void wxThreadGuiExit(void) static void wxThreadGuiExit()
{ {
gdk_input_remove(p_thrd_inid); gdk_input_remove(p_thrd_inid);
close(p_thrd_pipe[0]); close(p_thrd_pipe[0]);

View File

@@ -16,29 +16,35 @@
wxMutex::wxMutex() wxMutex::wxMutex()
{ {
m_locked = FALSE; m_locked = 0;
} }
wxMutex::~wxMutex() wxMutex::~wxMutex()
{ {
if (m_locked)
wxDebugMsg("wxMutex warning: destroying a locked mutex (%d locks)\n", m_locked);
} }
MutexError wxMutex::Lock() MutexError wxMutex::Lock()
{ {
m_locked = TRUE; m_locked++;
return NO_ERROR; return MUTEX_NO_ERROR;
} }
MutexError wxMutex::TryLock() MutexError wxMutex::TryLock()
{ {
m_locked = TRUE; if (m_locked > 0)
return NO_ERROR; return MUTEX_BUSY;
m_locked++;
return MUTEX_NO_ERROR;
} }
MutexError wxMutex::Unlock() MutexError wxMutex::Unlock()
{ {
m_locked = FALSE; if (m_locked == 0)
return NO_ERROR; return MUTEX_UNLOCKED;
m_locked--;
return MUTEX_NO_ERROR;
} }
wxCondition::wxCondition() wxCondition::wxCondition()
@@ -76,12 +82,12 @@ ThreadError wxThread::Create()
{ {
p_internal->exit_status = Entry(); p_internal->exit_status = Entry();
OnExit(); OnExit();
return NO_ERROR; return THREAD_NO_ERROR;
} }
ThreadError wxThread::Destroy() ThreadError wxThread::Destroy()
{ {
return RUNNING; return THREAD_RUNNING;
} }
void wxThread::DeferDestroy() void wxThread::DeferDestroy()
@@ -135,22 +141,23 @@ void wxThread::OnExit()
Join(); 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(); wxMainMutex.Lock();
return TRUE;
} }
// Global cleanup void wxThreadModule::wxThreadExit()
static void wxThreadExit(void *WXUNUSED(client))
{ {
wxMainMutex.Unlock(); wxMainMutex.Unlock();
} }
// Let automatic initialization be performed from wxCommonInit(). IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
static struct
wxThreadGlobal {
wxThreadGlobal() {
wxRegisterModuleFunction(wxThreadInit, wxThreadExit, NULL);
}
} dummy;

View File

@@ -51,13 +51,15 @@ wxMutex::wxMutex()
{ {
p_internal = new wxMutexInternal; p_internal = new wxMutexInternal;
pthread_mutex_init(&(p_internal->p_mutex), NULL); pthread_mutex_init(&(p_internal->p_mutex), NULL);
m_locked = false; m_locked = 0;
} }
wxMutex::~wxMutex() wxMutex::~wxMutex()
{ {
if (m_locked) if (m_locked > 0)
pthread_mutex_unlock(&(p_internal->p_mutex)); wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n",
m_locked);
pthread_mutex_destroy(&(p_internal->p_mutex)); pthread_mutex_destroy(&(p_internal->p_mutex));
delete p_internal; delete p_internal;
} }
@@ -67,9 +69,8 @@ wxMutexError wxMutex::Lock()
int err; int err;
err = pthread_mutex_lock(&(p_internal->p_mutex)); err = pthread_mutex_lock(&(p_internal->p_mutex));
switch (err) { if (err == EDEADLK)
case EDEADLK: return MUTEX_DEAD_LOCK; return MUTEX_DEAD_LOCK;
}
m_locked++; m_locked++;
return MUTEX_NO_ERROR; return MUTEX_NO_ERROR;
} }
@@ -90,7 +91,10 @@ wxMutexError wxMutex::TryLock()
wxMutexError wxMutex::Unlock() 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)); pthread_mutex_unlock(&(p_internal->p_mutex));
return MUTEX_NO_ERROR; return MUTEX_NO_ERROR;
} }

View File

@@ -46,34 +46,44 @@ public:
wxMutex::wxMutex() wxMutex::wxMutex()
{ {
m_locked = 0;
p_internal = new wxMutexInternal; p_internal = new wxMutexInternal;
init_lock(&(p_internal->p_mutex)); init_lock(&(p_internal->p_mutex));
} }
wxMutex::~wxMutex() 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)); 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) if (acquire_lock(&(p_internal->p_mutex)) != 0)
return BUSY; return MUTEX_BUSY;
return NO_ERROR; 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)); 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() {}
wxCondition::~wxCondition() {} wxCondition::~wxCondition() {}
@@ -116,16 +126,16 @@ void wxThread::Exit(void* status)
_exit(0); _exit(0);
} }
wxThread::ThreadError wxThread::Create() wxThreadError wxThread::Create()
{ {
if (p_internal->state != STATE_IDLE) if (p_internal->state != STATE_IDLE)
return RUNNING; return THREAD_RUNNING;
p_internal->state = STATE_RUNNING; p_internal->state = STATE_RUNNING;
if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) { if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
p_internal->state = STATE_IDLE; p_internal->state = STATE_IDLE;
return NO_RESOURCE; return THREAD_NO_RESOURCE;
} }
return NO_ERROR; return THREAD_NO_ERROR;
} }
void wxThread::Destroy() void wxThread::Destroy()

View File

@@ -61,6 +61,8 @@ wxMutex::wxMutex()
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); CloseHandle(p_internal->p_mutex);
} }