* fix a threading issue
This commit is contained in:
@@ -19,6 +19,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
//#define DEBUG_THREAD 1
|
||||
//#define DEBUG_MUTEX 1
|
||||
//#define DEBUG_CONDITION 1
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
@@ -30,13 +34,22 @@ Thread::Thread() :
|
||||
m_id(0),
|
||||
m_extant(false)
|
||||
{
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: Created thread object " << this << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
|
||||
#endif
|
||||
if (m_extant) {
|
||||
pthread_join(m_id, 0);
|
||||
}
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -47,6 +60,9 @@ Thread::start()
|
||||
cerr << "ERROR: thread creation failed" << endl;
|
||||
exit(1);
|
||||
} else {
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
|
||||
#endif
|
||||
m_extant = true;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +71,13 @@ void
|
||||
Thread::wait()
|
||||
{
|
||||
if (m_extant) {
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
|
||||
#endif
|
||||
pthread_join(m_id, 0);
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
|
||||
#endif
|
||||
m_extant = false;
|
||||
}
|
||||
}
|
||||
@@ -76,6 +98,9 @@ void *
|
||||
Thread::staticRun(void *arg)
|
||||
{
|
||||
Thread *thread = (Thread *)arg;
|
||||
#ifdef DEBUG_THREAD
|
||||
cerr << "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
|
||||
#endif
|
||||
thread->run();
|
||||
return 0;
|
||||
}
|
||||
@@ -83,22 +108,42 @@ Thread::staticRun(void *arg)
|
||||
Mutex::Mutex()
|
||||
{
|
||||
pthread_mutex_init(&m_mutex, 0);
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
|
||||
#endif
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
Mutex::lock()
|
||||
{
|
||||
if (m_locked) {
|
||||
cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
|
||||
}
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Want to lock mutex " << &m_mutex << endl;
|
||||
#endif
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
m_locked = true;
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Locked mutex " << &m_mutex << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Mutex::unlock()
|
||||
{
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Unlocking mutex " << &m_mutex << endl;
|
||||
#endif
|
||||
m_locked = false;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
@@ -106,8 +151,15 @@ bool
|
||||
Mutex::trylock()
|
||||
{
|
||||
if (pthread_mutex_trylock(&m_mutex)) {
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Mutex " << &m_mutex << " unavailable" << endl;
|
||||
#endif
|
||||
return false;
|
||||
} else {
|
||||
m_locked = true;
|
||||
#ifdef DEBUG_MUTEX
|
||||
cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -117,10 +169,16 @@ Condition::Condition()
|
||||
pthread_mutex_init(&m_mutex, 0);
|
||||
m_locked = false;
|
||||
pthread_cond_init(&m_condition, 0);
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
Condition::~Condition()
|
||||
{
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Destroying condition " << &m_condition << endl;
|
||||
#endif
|
||||
if (m_locked) pthread_mutex_unlock(&m_mutex);
|
||||
pthread_cond_destroy(&m_condition);
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
@@ -129,9 +187,36 @@ Condition::~Condition()
|
||||
void
|
||||
Condition::lock()
|
||||
{
|
||||
if (m_locked) return;
|
||||
if (m_locked) {
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Already locked " << &m_condition << endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << endl;
|
||||
#endif
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
m_locked = true;
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Condition::unlock()
|
||||
{
|
||||
if (!m_locked) {
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << endl;
|
||||
#endif
|
||||
m_locked = false;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -140,6 +225,9 @@ Condition::wait(int us)
|
||||
lock();
|
||||
if (us == 0) {
|
||||
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << endl;
|
||||
#endif
|
||||
pthread_cond_wait(&m_condition, &m_mutex);
|
||||
|
||||
} else {
|
||||
@@ -157,9 +245,15 @@ Condition::wait(int us)
|
||||
timeout.tv_sec = now.tv_sec;
|
||||
timeout.tv_nsec = now.tv_usec * 1000;
|
||||
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << endl;
|
||||
#endif
|
||||
pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << endl;
|
||||
#endif
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
m_locked = false;
|
||||
}
|
||||
@@ -167,6 +261,9 @@ Condition::wait(int us)
|
||||
void
|
||||
Condition::signal()
|
||||
{
|
||||
#ifdef DEBUG_CONDITION
|
||||
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << endl;
|
||||
#endif
|
||||
pthread_cond_signal(&m_condition);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user