mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
reference_counted_object and reference_counted_message specialisations
This commit is contained in:
parent
ecee02d41d
commit
dc25df16db
@ -104,46 +104,23 @@ namespace etl
|
||||
etl::reference_counted_object<TMessage, TCounter> rc_object;
|
||||
};
|
||||
|
||||
#if ETL_HAS_ATOMIC
|
||||
//***************************************************************************
|
||||
/// Class for creating reference counted messages using an atomic counter.
|
||||
/// \tparam TMessage The type to be reference counted.
|
||||
/// Persistent message type.
|
||||
/// The message type will always have a reference count of 1.
|
||||
/// \tparam TMessage The message type stored.
|
||||
//***************************************************************************
|
||||
template <typename TMessage>
|
||||
class atomic_counted_message : virtual public etl::reference_counted_message<TMessage, etl::atomic_int32_t>
|
||||
{
|
||||
public:
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
/// \param msg The message to count.
|
||||
//***************************************************************************
|
||||
atomic_counted_message(const TMessage& msg_)
|
||||
: reference_counted_message<TMessage, etl::atomic_int32_t>(msg_)
|
||||
{
|
||||
}
|
||||
|
||||
typedef typename reference_counted_message<TMessage, etl::atomic_int32_t>::message_type message_type;
|
||||
typedef typename reference_counted_message<TMessage, etl::atomic_int32_t>::counter_type counter_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
// Uncounted message type.
|
||||
//***************************************************************************
|
||||
template <typename TMessage>
|
||||
class reference_counted_message<TMessage, void> : virtual public etl::ireference_counted_message
|
||||
class persistent_message : virtual public etl::ireference_counted_message
|
||||
{
|
||||
public:
|
||||
|
||||
typedef TMessage message_type;
|
||||
typedef void counter_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor
|
||||
/// \param msg The message to count.
|
||||
//***************************************************************************
|
||||
reference_counted_message(const TMessage& msg_)
|
||||
persistent_message(const TMessage& msg_)
|
||||
: rc_object(msg_)
|
||||
{
|
||||
}
|
||||
@ -177,30 +154,23 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
// This class must not be default contructed, copy constructed or assigned.
|
||||
persistent_message() ETL_DELETE;
|
||||
persistent_message(const persistent_message&) ETL_DELETE;
|
||||
persistent_message& operator =(const persistent_message&) ETL_DELETE;
|
||||
|
||||
/// The reference counted object.
|
||||
etl::reference_counted_object<TMessage, void> rc_object;
|
||||
etl::persistent_object<TMessage> rc_object;
|
||||
};
|
||||
|
||||
#if ETL_CPP11_SUPPORTED && ETL_HAS_ATOMIC
|
||||
//***************************************************************************
|
||||
/// Synonym for reference_counted_message<TMessage, void>
|
||||
/// \tparam TObject The type stored in the object.
|
||||
/// Class for creating reference counted objects using an atomic counter.
|
||||
/// \tparam TObject The type to be reference counted.
|
||||
//***************************************************************************
|
||||
template <typename TMessage>
|
||||
class uncounted_message : public etl::reference_counted_message<TMessage, void>
|
||||
{
|
||||
public:
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
//***************************************************************************
|
||||
uncounted_message(const TMessage& msg_)
|
||||
: reference_counted_message<TMessage, void>(msg_)
|
||||
{
|
||||
}
|
||||
|
||||
typedef typename reference_counted_message<TMessage, void>::message_type message_type;
|
||||
typedef typename reference_counted_message<TMessage, void>::counter_type counter_type;
|
||||
};
|
||||
using atomic_counted_message = etl::reference_counted_message<TMessage, etl::atomic_int32_t>;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -72,7 +72,7 @@ namespace etl
|
||||
//};
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// Iterface for a reference counted message pool.
|
||||
//***************************************************************************
|
||||
class ireference_counted_message_pool
|
||||
{
|
||||
@ -83,7 +83,7 @@ namespace etl
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
/// A pool for allocating reference counted messages.
|
||||
//***************************************************************************
|
||||
template <typename TCounter>
|
||||
class reference_counted_message_pool : public ireference_counted_message_pool
|
||||
@ -98,13 +98,17 @@ namespace etl
|
||||
//{
|
||||
//}
|
||||
|
||||
reference_counted_message_pool()
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// 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");
|
||||
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>;
|
||||
|
||||
@ -135,7 +139,7 @@ namespace etl
|
||||
template <typename TMessage, typename... TArgs>
|
||||
etl::ireference_counted_message* allocate(TArgs&&... args)
|
||||
{
|
||||
//ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
|
||||
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>;
|
||||
|
||||
@ -298,15 +302,13 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Destruct a message and send it back to the pool.
|
||||
//*************************************************************************
|
||||
void release(const etl::ireference_counted_message* const prcm)
|
||||
void release(const etl::ireference_counted_message* const p_rcmessage)
|
||||
{
|
||||
std::cout << "reference_counted_message_pool : release\n";
|
||||
|
||||
if (prcm != ETL_NULLPTR)
|
||||
if (p_rcmessage != ETL_NULLPTR)
|
||||
{
|
||||
// prcm->~ireference_counted_message();
|
||||
delete prcm;
|
||||
//memory_block_pool.release_memory_block(prcm);
|
||||
// p_rcmessage->~ireference_counted_message();
|
||||
delete p_rcmessage;
|
||||
//memory_block_pool.release_memory_block(p_rcmessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,9 +325,9 @@ namespace etl
|
||||
/// The raw memory block pool.
|
||||
//imemory_block_pool& memory_block_pool;
|
||||
|
||||
//// Should not be copied.
|
||||
//message_pool(const message_pool&) ETL_DELETE;
|
||||
//message_pool& operator =(const message_pool&) ETL_DELETE;
|
||||
// Should not be copied.
|
||||
reference_counted_message_pool(const reference_counted_message_pool&) ETL_DELETE;
|
||||
reference_counted_message_pool& operator =(const reference_counted_message_pool&) ETL_DELETE;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -44,10 +44,10 @@ namespace etl
|
||||
public:
|
||||
|
||||
virtual ~ireference_counted_object() {};
|
||||
virtual void set_reference_count(uint32_t value) = 0;
|
||||
virtual void set_reference_count(int32_t value) = 0;
|
||||
virtual void increment_reference_count() = 0;
|
||||
ETL_NODISCARD virtual uint32_t decrement_reference_count() = 0;
|
||||
ETL_NODISCARD virtual uint32_t get_reference_count() const = 0;
|
||||
ETL_NODISCARD virtual int32_t decrement_reference_count() = 0;
|
||||
ETL_NODISCARD virtual int32_t get_reference_count() const = 0;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
@ -83,7 +83,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Set the reference count.
|
||||
//***************************************************************************
|
||||
virtual void set_reference_count(uint32_t value) ETL_OVERRIDE
|
||||
virtual void set_reference_count(int32_t value) ETL_OVERRIDE
|
||||
{
|
||||
reference_count = value;
|
||||
}
|
||||
@ -99,19 +99,19 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Decrement the refernce count.
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD virtual uint32_t decrement_reference_count() ETL_OVERRIDE
|
||||
ETL_NODISCARD virtual int32_t decrement_reference_count() ETL_OVERRIDE
|
||||
{
|
||||
assert(reference_count > 0);
|
||||
|
||||
return uint32_t(--reference_count);
|
||||
return int32_t(--reference_count);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Get the current reference count.
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD virtual uint32_t get_reference_count() const ETL_OVERRIDE
|
||||
ETL_NODISCARD virtual int32_t get_reference_count() const ETL_OVERRIDE
|
||||
{
|
||||
return uint32_t(reference_count);
|
||||
return int32_t(reference_count);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -125,46 +125,22 @@ namespace etl
|
||||
const TObject object; // The object being reference counted.
|
||||
};
|
||||
|
||||
#if ETL_HAS_ATOMIC
|
||||
//***************************************************************************
|
||||
/// Class for creating reference counted objects using an atomic counter.
|
||||
/// \tparam TObject The type to be reference counted.
|
||||
//***************************************************************************
|
||||
template <typename TObject>
|
||||
class atomic_counted_object : public etl::reference_counted_object<TObject, etl::atomic_int32_t>
|
||||
{
|
||||
public:
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
//***************************************************************************
|
||||
atomic_counted_object(const TObject& object_)
|
||||
: reference_counted_object<TObject, etl::atomic_int32_t>(object_)
|
||||
{
|
||||
}
|
||||
|
||||
typedef typename reference_counted_object<TObject, etl::atomic_int32_t>::value_type value_type;
|
||||
typedef typename reference_counted_object<TObject, etl::atomic_int32_t>::counter_type counter_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation creating objects that have the ireference_counted_object interface
|
||||
/// but do not actually count.
|
||||
/// Persistent message type.
|
||||
/// The message type will always have a reference count of 1.
|
||||
/// \tparam TObject The type stored in the object.
|
||||
//***************************************************************************
|
||||
template <typename TObject>
|
||||
class reference_counted_object<TObject, void> : public etl::ireference_counted_object
|
||||
class persistent_object : public etl::ireference_counted_object
|
||||
{
|
||||
public:
|
||||
|
||||
typedef TObject value_type;
|
||||
typedef void counter_type;
|
||||
typedef TObject value_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
//***************************************************************************
|
||||
reference_counted_object(const TObject& object_)
|
||||
persistent_object(const TObject& object_)
|
||||
: object(object_)
|
||||
{
|
||||
}
|
||||
@ -188,7 +164,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Set the reference count.
|
||||
//***************************************************************************
|
||||
virtual void set_reference_count(uint32_t value) ETL_OVERRIDE
|
||||
virtual void set_reference_count(int32_t) ETL_OVERRIDE
|
||||
{
|
||||
}
|
||||
|
||||
@ -202,7 +178,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Decrement the refernce count.
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD virtual uint32_t decrement_reference_count() ETL_OVERRIDE
|
||||
ETL_NODISCARD virtual int32_t decrement_reference_count() ETL_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -210,36 +186,29 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Get the current reference count.
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD virtual uint32_t get_reference_count() const ETL_OVERRIDE
|
||||
ETL_NODISCARD virtual int32_t get_reference_count() const ETL_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// This class must not be default contructed, copy constructed or assigned.
|
||||
persistent_object() ETL_DELETE;
|
||||
persistent_object(const persistent_object&) ETL_DELETE;
|
||||
persistent_object& operator =(const persistent_object&) ETL_DELETE;
|
||||
|
||||
TObject object; // The object being reference counted.
|
||||
};
|
||||
|
||||
#if ETL_CPP11_SUPPORTED && ETL_HAS_ATOMIC
|
||||
//***************************************************************************
|
||||
/// Synonym for reference_counted_object<TObject, void>
|
||||
/// \tparam TObject The type stored in the object.
|
||||
/// Class for creating reference counted objects using an atomic counter.
|
||||
/// \tparam TObject The type to be reference counted.
|
||||
//***************************************************************************
|
||||
template <typename TObject>
|
||||
class uncounted_object : public etl::reference_counted_object<TObject, void>
|
||||
{
|
||||
public:
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
//***************************************************************************
|
||||
uncounted_object(const TObject& object_)
|
||||
: reference_counted_object<TObject>(object_)
|
||||
{
|
||||
}
|
||||
|
||||
typedef typename reference_counted_object<TObject, void>::value_type value_type;
|
||||
typedef typename reference_counted_object<TObject, void>::counter_type counter_type;
|
||||
};
|
||||
using atomic_counted_object = etl::reference_counted_object<TObject, etl::atomic_int32_t>;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -31,8 +31,6 @@ SOFTWARE.
|
||||
#ifndef ETL_SHARED_MESSAGE_INCLUDED
|
||||
#define ETL_SHARED_MESSAGE_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "platform.h"
|
||||
#include "reference_counted_message_pool.h"
|
||||
#include "reference_counted_message.h"
|
||||
@ -57,15 +55,18 @@ namespace etl
|
||||
, p_rcmessage(&message_)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
|
||||
/// \param pmessage A reference to the message allocated from the pool.
|
||||
//*************************************************************************
|
||||
shared_message(etl::ireference_counted_message& message_)
|
||||
: p_rcmessage_owner(ETL_NULLPTR)
|
||||
, p_rcmessage(&message_)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -76,7 +77,6 @@ namespace etl
|
||||
, p_rcmessage(other.p_rcmessage)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -89,7 +89,6 @@ namespace etl
|
||||
// Deal with the current message.
|
||||
if (p_rcmessage->get_reference_counter().decrement_reference_count() == 0U)
|
||||
{
|
||||
std::cout << "shared_message =: Destroy reference counted message\n";
|
||||
if (p_rcmessage_owner != ETL_NULLPTR)
|
||||
{
|
||||
p_rcmessage_owner->release(p_rcmessage);
|
||||
@ -100,7 +99,6 @@ namespace etl
|
||||
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;
|
||||
@ -116,17 +114,8 @@ namespace etl
|
||||
{
|
||||
if (is_owned())
|
||||
{
|
||||
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 ~ : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,19 +151,27 @@ namespace etl
|
||||
etl::ireference_counted_message* p_rcmessage;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
/// A wrapper for reference counted messages.
|
||||
/// Contains pointers to a pool owner and a message defined with a ref count type.
|
||||
//*****************************************************************************
|
||||
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);
|
||||
etl::ireference_counted_message* p_rcmessage = owner.allocate(message);
|
||||
return etl::shared_message(*p_rcmessage, owner);
|
||||
}
|
||||
|
||||
#if ETL_CPP11_SUPPORTED
|
||||
//*****************************************************************************
|
||||
/// A wrapper for reference counted messages.
|
||||
/// Contains pointers to a pool owner and a message defined with a ref count type.
|
||||
//*****************************************************************************
|
||||
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);
|
||||
etl::ireference_counted_message* p_rcmessage = owner.allocate<TMessage>(etl::forward<TArgs>(args)...);
|
||||
return etl::shared_message(*p_rcmessage, owner);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user