more fixes for paused thread termination

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1958 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 1999-03-23 13:27:03 +00:00
parent d13c32e99d
commit 882eefb1f7

View File

@ -50,15 +50,19 @@
// constants
// ----------------------------------------------------------------------------
enum thread_state
// the possible states of the thread and transitions from them
enum wxThreadState
{
STATE_NEW, // didn't start execution yet (=> RUNNING)
STATE_RUNNING,
STATE_PAUSED,
STATE_CANCELED,
STATE_EXITED
STATE_RUNNING, // running (=> PAUSED or EXITED)
STATE_PAUSED, // suspended (=> RUNNING or EXITED)
STATE_EXITED // thread doesn't exist any more
};
// ----------------------------------------------------------------------------
// types
// ----------------------------------------------------------------------------
WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
// -----------------------------------------------------------------------------
@ -224,7 +228,7 @@ public:
// start the thread
wxThreadError Run();
// ask the thread to terminate
void Cancel();
void Wait();
// wake up threads waiting for our termination
void SignalExit();
// go to sleep until Resume() is called
@ -237,19 +241,19 @@ public:
int GetPriority() const { return m_prio; }
void SetPriority(int prio) { m_prio = prio; }
// state
thread_state GetState() const { return m_state; }
void SetState(thread_state state) { m_state = state; }
wxThreadState GetState() const { return m_state; }
void SetState(wxThreadState state) { m_state = state; }
// id
pthread_t GetId() const { return thread_id; }
pthread_t GetId() const { return m_threadId; }
pthread_t *GetIdPtr() { return &m_threadId; }
// "cancelled" flag
void SetCancelFlag() { m_cancelled = TRUE; }
bool WasCancelled() const { return m_cancelled; }
//private: -- should be!
pthread_t thread_id;
private:
thread_state m_state; // see thread_state enum
int m_prio; // in wxWindows units: from 0 to 100
pthread_t m_threadId; // id of the thread
wxThreadState m_state; // see wxThreadState enum
int m_prio; // in wxWindows units: from 0 to 100
// set when the thread should terminate
bool m_cancelled;
@ -346,17 +350,15 @@ wxThreadError wxThreadInternal::Run()
// starts executing and the mutex is still locked
}
void wxThreadInternal::Cancel()
void wxThreadInternal::Wait()
{
wxCHECK_RET( WasCancelled(), "thread should have been cancelled first" );
// if the thread we're waiting for is waiting for the GUI mutex, we will
// deadlock so make sure we release it temporarily
if ( wxThread::IsMain() )
wxMutexGuiLeave();
// nobody ever writes this variable so it's safe to not use any
// synchronization here
m_cancelled = TRUE;
// entering Wait() releases the mutex thus allowing SignalExit() to acquire
// it and to signal us its termination
m_cond.Wait(m_mutex);
@ -385,13 +387,15 @@ void wxThreadInternal::SignalExit()
void wxThreadInternal::Pause()
{
// the state is set from the thread which pauses us first, this function
// is called later so the state should have been already set
wxCHECK_RET( m_state == STATE_PAUSED,
"thread must first be paused with wxThread::Pause()." );
// don't pause the thread which is being terminated - this would lead to
// deadlock if the thread is paused after Delete() had called Resume() but
// before it had time to call Cancel()
if ( m_cancelled )
// before it had time to call Wait()
if ( WasCancelled() )
return;
// wait until the condition is signaled from Resume()
@ -481,7 +485,7 @@ wxThreadError wxThread::Create()
#endif // HAVE_THREAD_PRIORITY_FUNCTIONS
// create the new OS thread object
int rc = pthread_create(&p_internal->thread_id, &attr,
int rc = pthread_create(p_internal->GetIdPtr(), &attr,
wxThreadInternal::PthreadStart, (void *)this);
pthread_attr_destroy(&attr);
@ -549,7 +553,7 @@ unsigned int wxThread::GetPriority() const
unsigned long wxThread::GetID() const
{
return (unsigned long)p_internal->thread_id;
return (unsigned long)p_internal->GetId();
}
// -----------------------------------------------------------------------------
@ -597,9 +601,12 @@ wxThreadError wxThread::Resume()
wxThread::ExitCode wxThread::Delete()
{
m_critsect.Enter();
thread_state state = p_internal->GetState();
wxThreadState state = p_internal->GetState();
m_critsect.Leave();
// ask the thread to stop
p_internal->SetCancelFlag();
switch ( state )
{
case STATE_NEW:
@ -614,8 +621,8 @@ wxThread::ExitCode wxThread::Delete()
// fall through
default:
// set the flag telling to the thread to stop and wait
p_internal->Cancel();
// wait until the thread stops
p_internal->Wait();
}
return NULL;
@ -662,7 +669,7 @@ void wxThread::Exit(void *status)
// also test whether we were paused
bool wxThread::TestDestroy()
{
wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect);
wxCriticalSectionLocker lock(m_critsect);
if ( p_internal->GetState() == STATE_PAUSED )
{