I have a class, Queue, that I tried to make thread safe. It has these three member variables:
std::queue<T> m_queue;
pthread_mutex_t m_mutex;
pthread_cond_t m_condition;
and a push and pop implemented as:
template<class T> void Queue<T>::push(T value)
{
pthread_mutex_lock( &m_mutex );
m_queue.push(value);
if( !m_queue.empty() )
{
pthread_cond_signal( &m_condition );
}
pthread_mutex_unlock( &m_mutex );
}
template<class T> bool Queue<T>::pop(T& value, bool block)
{
bool rtn = false;
pthread_mutex_lock( &m_mutex );
if( block )
{
while( m_queue.empty() )
{
pthread_cond_wait( &m_condition, &m_mutex );
}
}
if( !m_queue.empty() )
{
value = m_queue.front();
m_queue.pop();
rtn = true;
}
pthread_mutex_unlock( &m_mutex );
return rtn;
}
Unfortunately there are occasional issues that may be the fault of this code. That is, there are two threads and sometimes thread 1 never comes out of push() and at other times thread 2 never comes out of pop() (the block parameter is true) though the queue isn't empty.
I understand there are other implementations available, but I'd like to try to fix this code, if needed. Anyone see any issues?
The constructor has the appropriate initializations:
Queue()
{
pthread_mutex_init( &mMutex, NULL );
pthread_cond_init( &mCondition, NULL );
}
and the destructor, the corresponding 'destroy' calls.