From 920dcdf4b657d3914d02f06f0d1154727abacb8b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 2 Jan 2021 12:35:13 +0000 Subject: [PATCH] Merged shared_message handlers into message_router --- include/etl/message_router.h | 313 ++++------------ include/etl/reference_counted_message.h | 22 +- include/etl/reference_counted_message_pool.h | 72 ++-- include/etl/reference_counted_object.h | 17 +- include/etl/shared_message.h | 104 +++--- include/etl/shared_message_processor.h | 354 ------------------- 6 files changed, 175 insertions(+), 707 deletions(-) delete mode 100644 include/etl/shared_message_processor.h diff --git a/include/etl/message_router.h b/include/etl/message_router.h index edc3900a..2790794e 100644 --- a/include/etl/message_router.h +++ b/include/etl/message_router.h @@ -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(); diff --git a/include/etl/reference_counted_message.h b/include/etl/reference_counted_message.h index d102a594..46e89771 100644 --- a/include/etl/reference_counted_message.h +++ b/include/etl/reference_counted_message.h @@ -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 - 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. diff --git a/include/etl/reference_counted_message_pool.h b/include/etl/reference_counted_message_pool.h index c50b2037..b7a8f79b 100644 --- a/include/etl/reference_counted_message_pool.h +++ b/include/etl/reference_counted_message_pool.h @@ -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 + etl::ireference_counted_message* allocate(const TMessage& message) + { + //ETL_STATIC_ASSERT((etl::is_base_of::value), "Not a message type"); + + using ref_message_t = etl::reference_counted_message; + + 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(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 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 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 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 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 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 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); } } diff --git a/include/etl/reference_counted_object.h b/include/etl/reference_counted_object.h index 1f4967b6..4b5fe33e 100644 --- a/include/etl/reference_counted_object.h +++ b/include/etl/reference_counted_object.h @@ -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 diff --git a/include/etl/shared_message.h b/include/etl/shared_message.h index b8e90838..d4154087 100644 --- a/include/etl/shared_message.h +++ b/include/etl/shared_message.h @@ -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 true 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 true 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 + 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 + etl::shared_message make_shared_message(TPool& owner, TArgs&&... args) + { + etl::ireference_counted_message* prcm = owner.allocate(etl::forward(args)...); + return etl::shared_message(*prcm, owner); + } +#endif } #endif diff --git a/include/etl/shared_message_processor.h b/include/etl/shared_message_processor.h deleted file mode 100644 index de913c24..00000000 --- a/include/etl/shared_message_processor.h +++ /dev/null @@ -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 - -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 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 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 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 - class shared_message_bus : public etl::ishared_message_bus - { - public: - - //******************************************* - /// Constructor. - //******************************************* - shared_message_bus() - : ishared_message_bus(processor_list) - { - } - - private: - - etl::vector processor_list; - }; -} - -#endif