Merged shared_message handlers into message_router

This commit is contained in:
John Wellbelove 2021-01-02 12:35:13 +00:00
parent 3cc95d6755
commit 920dcdf4b6
6 changed files with 175 additions and 707 deletions

View File

@ -56,6 +56,7 @@ SOFTWARE.
#include "platform.h"
#include "message.h"
#include "shared_message.h"
#include "message_packet.h"
#include "message_types.h"
#include "alignment.h"
@ -95,6 +96,13 @@ namespace etl
}
};
//***************************************************************************
/// Forward declare null message router functionality.
//***************************************************************************
class imessage_router;
etl::imessage_router& get_null_message_router();
//***************************************************************************
/// This is the base of all message routers.
//***************************************************************************
@ -103,14 +111,48 @@ namespace etl
public:
virtual ~imessage_router() {}
virtual void receive(const etl::imessage& message) = 0;
virtual void receive(imessage_router& source, const etl::imessage& message) = 0;
virtual void receive(imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& message) = 0;
virtual bool accepts(etl::message_id_t id) const = 0;
virtual bool is_null_router() const = 0;
virtual bool is_producer() const = 0;
virtual bool is_consumer() const = 0;
//********************************************
void receive(const etl::imessage& message)
{
receive(etl::get_null_message_router(), message);
}
//********************************************
void receive(imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& message)
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, message);
}
}
//********************************************
virtual void receive(imessage_router& source, etl::shared_message shared_msg)
{
receive(source, shared_msg.get_message());
}
//********************************************
void receive(etl::shared_message shared_msg)
{
receive(etl::get_null_message_router(), shared_msg);
}
//********************************************
void receive(imessage_router& source, etl::message_router_id_t destination_router_id, etl::shared_message shared_msg)
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, shared_msg);
}
}
//********************************************
bool accepts(const etl::imessage& msg) const
{
@ -187,21 +229,11 @@ namespace etl
{
}
//********************************************
void receive(const etl::imessage&) ETL_OVERRIDE
{
}
//********************************************
void receive(etl::imessage_router&, const etl::imessage&) ETL_OVERRIDE
{
}
//********************************************
void receive(imessage_router&, etl::message_router_id_t, const etl::imessage&) ETL_OVERRIDE
{
}
//********************************************
bool accepts(etl::message_id_t) const ETL_OVERRIDE
{
@ -234,6 +266,13 @@ namespace etl
}
};
//***********************************************
/// null message router functionality.
inline etl::imessage_router& get_null_message_router()
{
return etl::null_message_router::instance();
}
//***************************************************************************
/// This router can be used as a producer-only of messages, such an interrupt routine.
//***************************************************************************
@ -246,21 +285,11 @@ namespace etl
{
}
//********************************************
void receive(const etl::imessage&) ETL_OVERRIDE
{
}
//********************************************
void receive(etl::imessage_router&, const etl::imessage&) ETL_OVERRIDE
{
}
//********************************************
void receive(imessage_router&, etl::message_router_id_t, const etl::imessage&) ETL_OVERRIDE
{
}
//********************************************
bool accepts(etl::message_id_t) const ETL_OVERRIDE
{
@ -334,21 +363,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const etl::message_id_t id = msg.get_message_id();
@ -450,21 +466,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -565,21 +568,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -679,21 +669,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -791,21 +768,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -902,21 +866,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1012,21 +963,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1121,21 +1059,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1228,21 +1153,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1334,21 +1246,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1438,21 +1337,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1541,21 +1427,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1642,21 +1515,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1742,21 +1602,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1841,21 +1688,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();
@ -1939,21 +1773,8 @@ namespace etl
}
//**********************************************
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::null_message_router::instance(), msg);
}
using etl::imessage_router::receive;
//**********************************************
void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE
{
if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))
{
receive(source, msg);
}
}
//**********************************************
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
{
const size_t id = msg.get_message_id();

View File

@ -45,7 +45,6 @@ namespace etl
{
public:
virtual etl::imessage& get_message() = 0; ///< Get a reference to the message.
virtual const etl::imessage& get_message() const = 0; ///< Get a const reference to the message.
virtual etl::ireference_counted_object& get_reference_counter() = 0; ///< Get a reference to the reference counter.
@ -56,7 +55,7 @@ namespace etl
// Reference counted message type.
//***************************************************************************
template <typename TMessage, typename TCounter>
class reference_counted_message : virtual public etl::ireference_counted_message
class reference_counted_message : public etl::ireference_counted_message
{
public:
@ -70,16 +69,6 @@ namespace etl
reference_counted_message(const TMessage& msg_)
: rc_object(msg_)
{
rc_object.set_reference_count(0);
}
//***************************************************************************
/// Get a reference to the message.
/// \return A reference to the message.
//***************************************************************************
virtual TMessage& get_message() ETL_OVERRIDE
{
return rc_object.get_object();
}
//***************************************************************************
@ -159,15 +148,6 @@ namespace etl
{
}
//***************************************************************************
/// Get a reference to the message.
/// \return A reference to the message.
//***************************************************************************
virtual TMessage& get_message() ETL_OVERRIDE
{
return rc_object.get_object();
}
//***************************************************************************
/// Get a const reference to the message.
/// \return A const reference to the message.

View File

@ -82,24 +82,6 @@ namespace etl
virtual void release(const etl::ireference_counted_message& msg) = 0;
};
//***************************************************************************
///
//***************************************************************************
class null_reference_counted_message_pool : public ireference_counted_message_pool
{
public:
void release(const etl::ireference_counted_message* const pmsg) ETL_OVERRIDE
{
std::cout << "null_reference_counted_message_pool : destroy\n";
}
void release(const etl::ireference_counted_message& msg) ETL_OVERRIDE
{
std::cout << "null_reference_counted_message_pool : destroy\n";
}
};
//***************************************************************************
///
//***************************************************************************
@ -116,9 +98,39 @@ namespace etl
//{
//}
//*************************************************************************
/// Allocate a reference counted message from the pool.
//*************************************************************************
template <typename TMessage>
etl::ireference_counted_message* allocate(const TMessage& message)
{
//ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
using ref_message_t = etl::reference_counted_message<TMessage, TCounter>;
etl::ireference_counted_message* p = ETL_NULLPTR;
//if (sizeof(ref_message_t) <= memory_block_pool.get_memory_block_size(ref_message_t))
//{
// p = memory_block_pool.allocate_memory_block(sizeof(ref_message_t));
// if (p != ETL_NULLPTR)
// {
// ::new(p) ref_message_t(TMessage(etl::forward<TArgs>(args)...));
p = ::new ref_message_t(message);
// }
// else
// {
// ETL_ALWAYS_ASSERT(ETL_ERROR(etl::message_pool_allocation_failure));
// }
//}
return p;
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_REFERENCE_COUNTED_MESSAGE_POOL_FORCE_CPP03)
//*************************************************************************
/// Create a message from the pool.
/// Allocate a reference counted message from the pool.
//*************************************************************************
template <typename TMessage, typename... TArgs>
etl::ireference_counted_message* allocate(TArgs&&... args)
@ -148,7 +160,7 @@ namespace etl
}
#else
//*************************************************************************
/// Create a message from the pool. No parameters.
/// Allocate a reference counted message from the pool. No parameters.
//*************************************************************************
template <typename TMessage>
TMessage* allocate()
@ -175,7 +187,7 @@ namespace etl
}
//*************************************************************************
/// Create a message from the pool. One parameter.
/// Allocate a reference counted message from the pool. One parameter.
//*************************************************************************
template <typename TMessage, typename T1>
TMessage* allocate(const T1& t1)
@ -202,7 +214,7 @@ namespace etl
}
//*************************************************************************
/// Create a message from the pool. Two parameters.
/// Allocate a reference counted message from the pool. Two parameters.
//*************************************************************************
template <typename TMessage, typename T1, typename T2>
TMessage* allocate(const T1& t1, const T2& t2)
@ -229,7 +241,7 @@ namespace etl
}
//*************************************************************************
/// Create a message from the pool. Three parameters.
/// Allocate a reference counted message from the pool. Three parameters.
//*************************************************************************
template <typename TMessage, typename T1, typename T2, typename T3>
TMessage* allocate(const T1& t1, const T2& t2, const T3& t3)
@ -256,7 +268,7 @@ namespace etl
}
//*************************************************************************
/// Create a message from the pool. Four parameters.
/// Allocate a reference counted message from the pool. Four parameters.
//*************************************************************************
template <typename TMessage, typename T1, typename T2, typename T3, typename T4>
TMessage* allocate(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
@ -286,15 +298,15 @@ namespace etl
//*************************************************************************
/// Destruct a message and send it back to the pool.
//*************************************************************************
void release(const etl::ireference_counted_message* const pmsg)
void release(const etl::ireference_counted_message* const prcm)
{
std::cout << "reference_counted_message_pool : destroy\n";
std::cout << "reference_counted_message_pool : release\n";
if (pmsg != ETL_NULLPTR)
if (prcm != ETL_NULLPTR)
{
// pmsg->~ireference_counted_message();
delete pmsg;
//memory_block_pool.release_memory_block(pmsg);
// prcm->~ireference_counted_message();
delete prcm;
//memory_block_pool.release_memory_block(prcm);
}
}

View File

@ -71,15 +71,7 @@ namespace etl
{
reference_count = 0;
}
//***************************************************************************
/// Get a reference to the counted object.
//***************************************************************************
value_type& get_object()
{
return object;
}
//***************************************************************************
/// Get a const reference to the counted object.
//***************************************************************************
@ -122,8 +114,13 @@ namespace etl
private:
// This class must not be default contructed, copy constructed or assigned.
reference_counted_object() ETL_DELETE;
reference_counted_object(const reference_counted_object&) ETL_DELETE;
reference_counted_object& operator =(const reference_counted_object&) ETL_DELETE;
TCounter reference_count; // The reference counter
TObject object; // The object being reference counted.
const TObject object; // The object being reference counted.
};
#if ETL_HAS_ATOMIC

View File

@ -53,30 +53,30 @@ namespace etl
/// \param pmessage A reference to the message allocated from the pool.
//*************************************************************************
shared_message(etl::ireference_counted_message& message_, etl::ireference_counted_message_pool& owner_)
: p_message_owner(&owner_)
, p_message(&message_)
: p_rcmessage_owner(&owner_)
, p_rcmessage(&message_)
{
p_message->get_reference_counter().set_reference_count(1U);
std::cout << "shared_message C : Reference " << int(p_message->get_message().get_message_id()) << " " << p_message->get_reference_counter().get_reference_count() << "\n";
p_rcmessage->get_reference_counter().set_reference_count(1U);
std::cout << "shared_message C : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
shared_message(etl::ireference_counted_message& message_)
: p_message_owner(ETL_NULLPTR)
, p_message(&message_)
: p_rcmessage_owner(ETL_NULLPTR)
, p_rcmessage(&message_)
{
p_message->get_reference_counter().set_reference_count(1U);
std::cout << "shared_message C : Reference " << int(p_message->get_message().get_message_id()) << " No Owner\n";
p_rcmessage->get_reference_counter().set_reference_count(1U);
std::cout << "shared_message C : ID = " << int(p_rcmessage->get_message().get_message_id()) << " No Owner\n";
}
//*************************************************************************
/// Copy constructor
//*************************************************************************
shared_message(const shared_message& other)
: p_message_owner(other.p_message_owner)
, p_message(other.p_message)
: p_rcmessage_owner(other.p_rcmessage_owner)
, p_rcmessage(other.p_rcmessage)
{
p_message->get_reference_counter().increment_reference_count();
std::cout << "shared_message CC : Reference " << int(p_message->get_message().get_message_id()) << " " << p_message->get_reference_counter().get_reference_count() << "\n";
p_rcmessage->get_reference_counter().increment_reference_count();
std::cout << "shared_message CC : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
//*************************************************************************
@ -87,20 +87,20 @@ namespace etl
if (&other != this)
{
// Deal with the current message.
if (p_message->get_reference_counter().decrement_reference_count() == 0U)
if (p_rcmessage->get_reference_counter().decrement_reference_count() == 0U)
{
std::cout << "shared_message =: Destroy reference counted message\n";
if (p_message_owner != ETL_NULLPTR)
if (p_rcmessage_owner != ETL_NULLPTR)
{
p_message_owner->release(p_message);
p_rcmessage_owner->release(p_rcmessage);
}
}
// Copy over the new one.
p_message_owner = other.p_message_owner;
p_message = other.p_message;
p_message->get_reference_counter().increment_reference_count();
std::cout << "shared_message =: Reference " << int(p_message->get_message().get_message_id()) << " " << p_message->get_reference_counter().get_reference_count() << "\n";
p_rcmessage_owner = other.p_rcmessage_owner;
p_rcmessage = other.p_rcmessage;
p_rcmessage->get_reference_counter().increment_reference_count();
std::cout << "shared_message =: ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
return *this;
@ -112,42 +112,30 @@ namespace etl
//*************************************************************************
~shared_message()
{
if (p_message->get_reference_counter().decrement_reference_count() == 0U)
{
std::cout << "shared_message ~: Destroy reference counted message\n";
if (p_message_owner != ETL_NULLPTR)
if (p_rcmessage->get_reference_counter().decrement_reference_count() == 0U)
{
if (is_owned())
{
p_message_owner->release(p_message);
std::cout << "shared_message ~: Destroy reference counted message\n";
p_rcmessage_owner->release(p_rcmessage);
}
else
{
std::cout << "shared_message ~: Uncounted message\n";
}
}
else
{
std::cout << "shared_message ~: Reference " << int(p_message->get_message().get_message_id()) << " " << p_message->get_reference_counter().get_reference_count() << "\n";
std::cout << "shared_message ~ : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
}
//*************************************************************************
/// Get a pointer to the contained message.
//*************************************************************************
etl::imessage& get_message()
{
return p_message->get_message();
}
//*************************************************************************
/// Get a const pointer to the contained message.
/// Get a const reference to the contained message.
//*************************************************************************
const etl::imessage& get_message() const
{
return p_message->get_message();
}
//*************************************************************************
/// Returns <b>true</b> if the shared message is owned by a pool.
//*************************************************************************
bool is_owned() const
{
return (p_message_owner != ETL_NULLPTR);
return p_rcmessage->get_message();
}
//*************************************************************************
@ -155,16 +143,40 @@ namespace etl
//*************************************************************************
uint32_t get_reference_count() const
{
return p_message->get_reference_counter().get_reference_count();
return p_rcmessage->get_reference_counter().get_reference_count();
}
private:
//*************************************************************************
/// Returns <b>true</b> if the internal reference counted message is owned by a pool.
//*************************************************************************
bool is_owned() const
{
return (p_rcmessage_owner != ETL_NULLPTR);
}
shared_message() ETL_DELETE;
etl::ireference_counted_message_pool* p_message_owner;
etl::ireference_counted_message* p_message;
etl::ireference_counted_message_pool* p_rcmessage_owner;
etl::ireference_counted_message* p_rcmessage;
};
template <typename TPool, typename TMessage>
etl::shared_message make_shared_message(TPool& owner, const TMessage& message)
{
etl::ireference_counted_message* prcm = owner.allocate(message);
return etl::shared_message(*prcm, owner);
}
#if ETL_CPP11_SUPPORTED
template <typename TMessage, typename TPool, typename... TArgs>
etl::shared_message make_shared_message(TPool& owner, TArgs&&... args)
{
etl::ireference_counted_message* prcm = owner.allocate<TMessage>(etl::forward<TArgs>(args)...);
return etl::shared_message(*prcm, owner);
}
#endif
}
#endif

View File

@ -1,354 +0,0 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2020 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_SHARED_MESSAGE_PROCESSOR_INCLUDED
#define ETL_SHARED_MESSAGE_PROCESSOR_INCLUDED
#include "platform.h"
#include "shared_message.h"
#include "vector.h"
#include <stdint.h>
namespace etl
{
typedef uint_least8_t shared_message_processor_id_t;
//***************************************************************************
/// This is the base of all shared message processors.
//***************************************************************************
class ishared_message_processor
{
public:
//***************************************************************************
///
//***************************************************************************
ishared_message_processor(etl::shared_message_processor_id_t id_ = etl::shared_message_processor_id_t())
: id(id_)
{
}
virtual void receive(etl::shared_message shared_msg) = 0;
virtual void receive(shared_message_processor_id_t destination_processor_id, etl::shared_message shared_msg) = 0;
virtual bool accepts(etl::message_id_t id) const = 0;
//***************************************************************************
///
//***************************************************************************
bool accepts(etl::shared_message shared_msg) const
{
return accepts(shared_msg.get_message().get_message_id());
}
//***************************************************************************
///
//***************************************************************************
shared_message_processor_id_t get_shared_message_processor_id() const
{
return id;
}
enum
{
NULL_SHARED_MESSAGE_PROCESSOR = 255,
SHARED_MESSAGE_BUS = 254,
ALL_SHARED_MESSAGE_PROCESSORS = 253,
MAX_SHARED_MESSAGE_PROCESSOR = 249
};
protected:
etl::shared_message_processor_id_t id;
};
//***************************************************************************
/// Derive user defined shared message processors from this.
//***************************************************************************
class shared_message_processor : public ishared_message_processor
{
public:
//***************************************************************************
///
//***************************************************************************
shared_message_processor(etl::shared_message_processor_id_t id_ = etl::shared_message_processor_id_t())
: ishared_message_processor(id_)
{
}
etl::ishared_message_processor::receive;
//***************************************************************************
///
//***************************************************************************
void receive(etl::shared_message shared_msg)
{
on_receive(shared_msg);
}
//***************************************************************************
///
//***************************************************************************
void receive(shared_message_processor_id_t destination_processor_id, etl::shared_message shared_msg)
{
if (destination_processor_id == id)
{
on_receive(shared_msg);
}
}
// User overridden.
virtual void on_receive(etl::shared_message shared_msg) = 0;
};
//***************************************************************************
/// Interface for shared message bus
//***************************************************************************
class ishared_message_bus : public etl::ishared_message_processor
{
private:
typedef etl::ivector<etl::ishared_message_processor*> processor_list_t;
public:
using etl::ishared_message_processor::receive;
//*******************************************
/// Subscribe to the bus.
//*******************************************
bool subscribe(etl::ishared_message_processor& processor)
{
bool ok = true;
ok = !processor_list.full();
ETL_ASSERT(ok, ETL_ERROR(etl::shared_message_bus_too_many_subscribers));
if (ok)
{
processor_list_t::iterator iprocessor = etl::upper_bound(processor_list.begin(),
processor_list.end(),
processor.get_shared_message_processor_id(),
compare_processor_id());
processor_list.insert(iprocessor, &processor);
}
return ok;
}
//*******************************************
/// Unsubscribe from the bus.
//*******************************************
void unsubscribe(etl::shared_message_processor_id_t id)
{
if (id == etl::ishared_message_bus::ALL_SHARED_MESSAGE_PROCESSORS)
{
clear();
}
else
{
ETL_OR_STD::pair<processor_list_t::iterator, processor_list_t::iterator> range = etl::equal_range(processor_list.begin(),
processor_list.end(),
id,
compare_processor_id());
processor_list.erase(range.first, range.second);
}
}
//*******************************************
void unsubscribe(etl::shared_message_processor& processor)
{
processor_list_t::iterator iprocessor = etl::find(processor_list.begin(),
processor_list.end(),
&processor);
if (iprocessor != processor_list.end())
{
processor_list.erase(iprocessor);
}
}
//*******************************************
void receive(shared_message shared_msg) ETL_OVERRIDE
{
receive(etl::shared_message_processor::ALL_SHARED_MESSAGE_PROCESSORS, shared_msg);
}
//*******************************************
void receive(etl::shared_message_processor_id_t destination_processor_id,
etl::shared_message shared_msg) ETL_OVERRIDE
{
switch (destination_processor_id)
{
//*****************************
// Broadcast to all processors.
case etl::shared_message_processor::ALL_SHARED_MESSAGE_PROCESSORS:
{
processor_list_t::iterator iprocessor = processor_list.begin();
// Broadcast to everyone.
while (iprocessor != processor_list.end())
{
etl::ishared_message_processor& processor = **iprocessor;
if (processor.accepts(shared_msg.get_message().get_message_id()))
{
processor.receive(shared_msg);
}
++iprocessor;
}
break;
}
//*****************************
// Must be an addressed shared_msg.
default:
{
processor_list_t::iterator iprocessor = processor_list.begin();
// Find processors with the id.
ETL_OR_STD::pair<processor_list_t::iterator, processor_list_t::iterator> range = etl::equal_range(processor_list.begin(),
processor_list.end(),
destination_processor_id,
compare_processor_id());
// Call all of them.
while (range.first != range.second)
{
if ((*(range.first))->accepts(shared_msg.get_message().get_message_id()))
{
(*(range.first))->receive(shared_msg);
}
++range.first;
}
// Do any message buses.
// These are always at the end of the list.
iprocessor = etl::lower_bound(processor_list.begin(),
processor_list.end(),
etl::ishared_message_bus::SHARED_MESSAGE_BUS,
compare_processor_id());
while (iprocessor != processor_list.end())
{
// So pass it on.
(*iprocessor)->receive(destination_processor_id, shared_msg);
++iprocessor;
}
break;
}
}
}
using ishared_message_processor::accepts;
//*******************************************
/// Does this message bus accept the message id?
/// Yes!, it accepts everything!
//*******************************************
bool accepts(etl::message_id_t) const ETL_OVERRIDE
{
return true;
}
//*******************************************
size_t size() const
{
return processor_list.size();
}
//*******************************************
void clear()
{
return processor_list.clear();
}
protected:
//*******************************************
/// Constructor.
//*******************************************
ishared_message_bus(processor_list_t& list)
: ishared_message_processor(etl::ishared_message_processor::SHARED_MESSAGE_BUS)
, processor_list(list)
{
}
private:
//*******************************************
// How to compare processors to processor ids.
//*******************************************
struct compare_processor_id
{
bool operator()(const etl::ishared_message_processor* prouter, etl::shared_message_processor_id_t id) const
{
return prouter->get_shared_message_processor_id() < id;
}
bool operator()(etl::shared_message_processor_id_t id, const etl::ishared_message_processor* prouter) const
{
return id < prouter->get_shared_message_processor_id();
}
};
processor_list_t& processor_list;
};
//***************************************************************************
/// The message bus
//***************************************************************************
template <uint_least8_t MAX_PROCESSORS_>
class shared_message_bus : public etl::ishared_message_bus
{
public:
//*******************************************
/// Constructor.
//*******************************************
shared_message_bus()
: ishared_message_bus(processor_list)
{
}
private:
etl::vector<etl::shared_message_processor*, MAX_PROCESSORS_> processor_list;
};
}
#endif