2005-06-25 04:21:26 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2005-06-28 01:04:34 +02:00
|
|
|
#include "MessagePasserImpl.h"
|
2005-10-09 05:26:16 +02:00
|
|
|
#include "Messages.h"
|
2005-06-25 04:21:26 +02:00
|
|
|
|
2005-10-09 05:26:16 +02:00
|
|
|
#include "lib/timer.h"
|
2005-08-20 17:44:50 +02:00
|
|
|
|
2005-06-25 04:21:26 +02:00
|
|
|
using namespace AtlasMessage;
|
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
|
2005-10-31 04:36:50 +01:00
|
|
|
MessagePasserImpl::MessagePasserImpl()
|
2005-10-09 05:26:16 +02:00
|
|
|
: m_Trace(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2005-10-31 04:36:50 +01:00
|
|
|
void MessagePasserImpl::Add(IMessage* msg)
|
2005-06-25 04:21:26 +02:00
|
|
|
{
|
2005-08-20 17:44:50 +02:00
|
|
|
debug_assert(msg);
|
2005-10-31 04:36:50 +01:00
|
|
|
debug_assert(msg->GetType() == IMessage::Message);
|
2005-08-20 17:44:50 +02:00
|
|
|
|
2005-10-09 05:26:16 +02:00
|
|
|
if (m_Trace)
|
2005-10-31 04:36:50 +01:00
|
|
|
debug_printf("%8.3f add message: %s\n", get_time(), msg->GetName());
|
2005-10-09 05:26:16 +02:00
|
|
|
|
2005-06-25 04:21:26 +02:00
|
|
|
m_Mutex.Lock();
|
|
|
|
m_Queue.push(msg);
|
|
|
|
m_Mutex.Unlock();
|
|
|
|
}
|
|
|
|
|
2005-10-31 04:36:50 +01:00
|
|
|
IMessage* MessagePasserImpl::Retrieve()
|
2005-06-25 04:21:26 +02:00
|
|
|
{
|
2005-07-03 18:25:48 +02:00
|
|
|
// (It should be fairly easy to use a more efficient thread-safe queue,
|
|
|
|
// since there's only one thread adding items and one thread consuming;
|
|
|
|
// but it's not worthwhile yet.)
|
|
|
|
|
2005-06-25 04:21:26 +02:00
|
|
|
m_Mutex.Lock();
|
|
|
|
|
2005-10-31 04:36:50 +01:00
|
|
|
IMessage* msg = NULL;
|
2005-06-25 04:21:26 +02:00
|
|
|
if (! m_Queue.empty())
|
|
|
|
{
|
|
|
|
msg = m_Queue.front();
|
|
|
|
m_Queue.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Mutex.Unlock();
|
|
|
|
|
2005-10-09 05:26:16 +02:00
|
|
|
// if (m_Trace && msg) debug_printf("%8.3f retrieved message: %s\n", get_time(), msg->GetType());
|
2005-08-20 17:44:50 +02:00
|
|
|
|
2005-06-25 04:21:26 +02:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
2005-10-31 04:36:50 +01:00
|
|
|
void MessagePasserImpl::Query(QueryMessage* qry)
|
|
|
|
{
|
|
|
|
debug_assert(qry);
|
|
|
|
debug_assert(qry->GetType() == IMessage::Query);
|
|
|
|
|
|
|
|
if (m_Trace)
|
|
|
|
debug_printf("%8.3f add query: %s\n", get_time(), qry->GetName());
|
|
|
|
|
|
|
|
// Initialise a semaphore, so we can block until the query has been handled
|
|
|
|
int err;
|
|
|
|
sem_t sem;
|
|
|
|
err = sem_init(&sem, 0, 0);
|
|
|
|
if (err != 0)
|
|
|
|
{
|
|
|
|
// Probably-fatal error
|
|
|
|
debug_warn("sem_init failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
qry->m_Semaphore = (void*)&sem;
|
|
|
|
|
|
|
|
m_Mutex.Lock();
|
|
|
|
m_Queue.push(qry);
|
|
|
|
m_Mutex.Unlock();
|
|
|
|
|
|
|
|
// Wait until the query handler has handled the query and called sem_post
|
|
|
|
while (0 != (err = sem_wait(&sem)))
|
|
|
|
{
|
|
|
|
// Keep retrying while EINTR
|
|
|
|
if (errno != EINTR)
|
|
|
|
{
|
|
|
|
// Other errors are probably fatal
|
|
|
|
debug_warn("sem_wait failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
qry->m_Semaphore = NULL;
|
|
|
|
sem_destroy(&sem);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MessagePasserImpl::IsEmpty()
|
2005-06-25 04:21:26 +02:00
|
|
|
{
|
2005-09-13 05:57:34 +02:00
|
|
|
m_Mutex.Lock();
|
|
|
|
bool empty = m_Queue.empty();
|
|
|
|
m_Mutex.Unlock();
|
|
|
|
return empty;
|
2005-06-25 04:21:26 +02:00
|
|
|
}
|
|
|
|
|
2005-10-31 04:36:50 +01:00
|
|
|
void MessagePasserImpl::SetTrace(bool t)
|
2005-10-09 05:26:16 +02:00
|
|
|
{
|
|
|
|
m_Trace = t;
|
|
|
|
}
|