#pragma once
#include "env.h"
#include "p8-platform/threads/mutex.h"
namespace CEC
{
using namespace P8PLATFORM;
class CAdapterMessageQueueEntry
{
public:
CAdapterMessageQueueEntry(const cec_command &command)
: m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false)
{
m_hash = hashValue(
uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE),
command.initiator, command.destination);
}
virtual ~CAdapterMessageQueueEntry(void) {}
uint32_t Result() const
{
return m_retval;
}
void Broadcast(void)
{
CLockObject lock(m_mutex);
m_condition.Broadcast();
}
bool CheckMatch(uint32_t opcode, cec_logical_address initiator,
cec_logical_address destination, uint32_t response)
{
uint32_t hash = hashValue(opcode, initiator, destination);
if (hash == m_hash)
{
CLockObject lock(m_mutex);
m_retval = response;
m_bSucceeded = true;
m_condition.Signal();
return true;
}
return false;
}
bool Wait(uint32_t iTimeout)
{
CLockObject lock(m_mutex);
bool bReturn = m_bSucceeded ? true : m_condition.Wait(m_mutex, m_bSucceeded, iTimeout);
m_bWaiting = false;
return bReturn;
}
bool IsWaiting(void)
{
CLockObject lock(m_mutex);
return m_bWaiting;
}
static uint32_t hashValue(uint32_t opcode,
cec_logical_address initiator,
cec_logical_address destination)
{
return 1 | ((uint32_t)initiator << 8) |
((uint32_t)destination << 16) | ((uint32_t)opcode << 16);
}
private:
bool m_bWaiting;
P8PLATFORM::CCondition<bool> m_condition;
P8PLATFORM::CMutex m_mutex;
uint32_t m_hash;
uint32_t m_retval;
bool m_bSucceeded;
};
};