2
3
6
7
8
15#include <so_5/types.hpp>
16#include <so_5/exception.hpp>
18#include <so_5/spinlocks.hpp>
20#include <so_5/msg_tracing.hpp>
22#include <so_5/mbox.hpp>
23#include <so_5/enveloped_msg.hpp>
25#include <so_5/impl/local_mbox_basic_subscription_info.hpp>
27#include <so_5/impl/msg_tracing_helpers.hpp>
29#include <so_5/details/invoke_noexcept_code.hpp>
44
45
46
47
48
49
50
51
55
56
57
58
59
60
61
91
92
108
109
174 if( storage_type::vector == m_storage )
175 return m_it_v->m_info;
177 return m_it_m->second;
183 return std::addressof(**
this);
189 if( storage_type::vector == m_storage )
217 if( storage_type::vector == m_storage )
218 return m_it_v == o.m_it_v;
220 return m_it_m == o.m_it_m;
226 return !( *
this == o );
250 if( storage_type::vector == m_storage )
251 return m_it_v->m_info;
253 return m_it_m->second;
259 return std::addressof(**
this);
265 if( storage_type::vector == m_storage )
293 if( storage_type::vector == m_storage )
294 return m_it_v == o.m_it_v;
296 return m_it_m == o.m_it_m;
302 return !( *
this == o );
321 const auto insertion_place = std::lower_bound(
325 subscribers_vector_item_comparator{} );
326 m_vector.insert( insertion_place, std::move(new_item) );
335 m_map.emplace( std::addressof(sink_as_key), std::move(info) );
348 vector_type empty_vector;
349 map_type new_storage;
352 std::for_each( m_vector.begin(), m_vector.end(),
353 [&new_storage](
const subscribers_vector_item_t & item ) {
354 new_storage.emplace( item.m_sink_as_key, item.m_info );
360 swap( m_map, new_storage );
361 swap( m_vector, empty_vector );
381 vector_type new_storage;
385 new_storage.reserve( m_map.size() );
392 std::for_each( m_map.begin(), m_map.end(),
393 [&new_storage](
const map_type::value_type & info ) {
394 new_storage.emplace_back( *(info.first), info.second );
401 swap( m_vector, new_storage );
402 swap( m_map, empty_map );
414 auto pos = std::lower_bound(
418 subscribers_vector_item_comparator{} );
419 if( pos != m_vector.end()
420 && pos->m_sink_as_key == std::addressof(subscriber) )
421 return iterator{ pos };
423 return iterator{ m_vector.end() };
429 return iterator{ m_map.find( std::addressof(subscriber) ) };
462 swap( a.m_vector, b.m_vector );
463 swap( a.m_map, b.m_map );
491 if( m_vector.size() == size_limits::switch_to_map )
496 insert_to_vector( sink_as_key, std::move( info ) );
498 insert_to_map( sink_as_key, std::move( info ) );
501 template<
typename... Args >
513 m_vector.erase( it.m_it_v );
516 m_map.erase( it.m_it_m );
519 if( m_map.size() < size_limits::switch_to_vector )
537 return iterator{ m_vector.begin() };
539 return iterator{ m_map.begin() };
546 return iterator{ m_vector.end() };
548 return iterator{ m_map.end() };
555 return const_iterator{ m_vector.begin() };
557 return const_iterator{ m_map.begin() };
564 return const_iterator{ m_vector.end() };
566 return const_iterator{ m_map.end() };
573 return m_vector.empty();
575 return m_map.empty();
582 return m_vector.size();
593
594
595
596
597
636
637
638
639
640
641
642template<
typename Tracing_Base >
646 ,
private Tracing_Base
649 template<
typename... Tracing_Args >
656 Tracing_Args &&... args )
669 const std::type_index & type_wrapper,
687 const std::type_index & type_wrapper,
702 s <<
"<mbox:type=MPMC:id=" <<
m_id <<
">";
716 const std::type_index & msg_type,
717 const message_ref_t & message,
718 unsigned int redirection_deep )
override
741 const std::type_index & msg_type,
760 const std::type_index & msg_type,
778 template<
typename Info_Maker,
typename Info_Changer >
781 const std::type_index & type_wrapper,
784 Info_Changer changer )
815 template<
typename Info_Changer >
818 const std::type_index & type_wrapper,
820 Info_Changer changer )
848 typename Tracing_Base::deliver_op_tracer
const & tracer,
850 const std::type_index & msg_type,
851 const message_ref_t & message,
852 unsigned int redirection_deep )
875 typename Tracing_Base::deliver_op_tracer
const & tracer,
877 const std::type_index & msg_type,
878 const message_ref_t & message,
879 unsigned int redirection_deep )
const
904
905
906
907
908
909
910
911
914 const std::type_index & msg_type,
915 const message_ref_t & what )
const
921 "an attempt to deliver mutable message via MPMC mbox"
927
928
929
930
931
932using local_mbox_without_tracing =
936
937
938
939
940
941using local_mbox_with_tracing =
Interface for message sink.
static bool special_sink_ptr_compare(const abstract_message_sink_t *a, const abstract_message_sink_t *b) noexcept
Interface for creator of new mbox in OOP style.
An interface of delivery filter object.
const subscription_info_with_sink_t * operator->() const
const subscription_info_with_sink_t & operator*() const
const_map_iterator_type m_it_m
const_vector_iterator_type m_it_v
const_iterator & operator++()
const_iterator(const_vector_iterator_type it_v)
bool operator!=(const const_iterator &o) const
bool operator==(const const_iterator &o) const
const_iterator operator++(int)
bool operator==(const iterator &o) const
vector_iterator_type m_it_v
iterator(vector_iterator_type it_v)
subscription_info_with_sink_t & operator*()
bool operator!=(const iterator &o) const
subscription_info_with_sink_t * operator->()
A special container for holding subscriber_info objects.
subscriber_adaptive_container_t(const subscriber_adaptive_container_t &o)
Copy constructor.
bool is_vector() const
Is vector used as a storage.
storage_type m_storage
The current storage type to be used by container.
subscriber_adaptive_container_t & operator=(subscriber_adaptive_container_t &&o) noexcept
Move operator.
void insert_to_vector(abstract_message_sink_t &sink_as_key, subscription_info_with_sink_t &&info)
Insertion of new item to vector.
void emplace(abstract_message_sink_t &sink_as_key, Args &&... args)
friend void swap(subscriber_adaptive_container_t &a, subscriber_adaptive_container_t &b) noexcept
const_iterator begin() const
const_iterator end() const
vector_type m_vector
Container for small amount of subscriber_infos.
void insert(abstract_message_sink_t &sink_as_key, subscription_info_with_sink_t info)
subscriber_adaptive_container_t()
Default constructor.
void insert_to_map(abstract_message_sink_t &sink_as_key, subscription_info_with_sink_t &&info)
Insertion of new item to map.
subscriber_adaptive_container_t(subscriber_adaptive_container_t &&o) noexcept
Move constructor.
void switch_storage_to_map()
Switching storage from vector to map.
iterator find(abstract_message_sink_t &subscriber)
map_type m_map
Container for large amount of subscriber_infos.
iterator find_in_vector(abstract_message_sink_t &subscriber)
subscriber_adaptive_container_t & operator=(const subscriber_adaptive_container_t &o)
Copy operator.
iterator find_in_map(abstract_message_sink_t &subscriber)
void switch_storage_to_vector()
Switching storage from map to vector.
void erase(const iterator &it)
An information block about one subscription to one message type with presence of message_sink.
A template with implementation of local mbox.
mbox_type_t type() const override
Get the type of message box.
environment_t & environment() const noexcept override
SObjectizer Environment for which the mbox is created.
mbox_id_t id() const override
Unique ID of this mbox.
void do_deliver_message_impl(typename Tracing_Base::deliver_op_tracer const &tracer, message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const message_ref_t &message, unsigned int redirection_deep)
void set_delivery_filter(const std::type_index &msg_type, const delivery_filter_t &filter, abstract_message_sink_t &subscriber) override
Set a delivery filter for message type and subscriber.
void do_deliver_message_to_subscriber(const local_mbox_details::subscription_info_with_sink_t &subscriber_info, typename Tracing_Base::deliver_op_tracer const &tracer, message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const message_ref_t &message, unsigned int redirection_deep) const
void ensure_immutable_message(const std::type_index &msg_type, const message_ref_t &what) const
Ensures that message is an immutable message.
local_mbox_template(mbox_id_t id, environment_t &env, Tracing_Args &&... args)
void modify_and_remove_subscriber_if_needed(const std::type_index &type_wrapper, abstract_message_sink_t &subscriber, Info_Changer changer)
void do_deliver_message(message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const message_ref_t &message, unsigned int redirection_deep) override
Deliver message for all subscribers with respect to message limits.
void subscribe_event_handler(const std::type_index &type_wrapper, abstract_message_sink_t &subscriber) override
Add the message handler.
void unsubscribe_event_handler(const std::type_index &type_wrapper, abstract_message_sink_t &subscriber) noexcept override
Remove all message handlers.
std::string query_name() const override
Get the mbox name.
void insert_or_modify_subscriber(const std::type_index &type_wrapper, abstract_message_sink_t &subscriber, Info_Maker maker, Info_Changer changer)
void drop_delivery_filter(const std::type_index &msg_type, abstract_message_sink_t &subscriber) noexcept override
Removes delivery filter for message type and subscriber.
mbox_t create_ordinary_mpsc_mbox(environment_t &env, agent_t &owner)
Create mpsc_mbox that handles message limits.
mbox_t create_limitless_mpsc_mbox(environment_t &env, agent_t &owner)
Create mpsc_mbox that ignores message limits.
mbox_t introduce_named_mbox(mbox_namespace_name_t mbox_namespace, nonempty_name_t mbox_name, const std::function< mbox_t() > &mbox_factory)
Introduce named mbox with user-provided factory.
mbox_core_t(outliving_reference_t< so_5::msg_tracing::holder_t > msg_tracing_stuff)
mbox_t create_custom_mbox(environment_t &env, ::so_5::custom_mbox_details::creator_iface_t &creator)
Create a custom mbox.
void destroy_mbox(const full_named_mbox_id_t &name) noexcept
Remove a reference to the named mbox.
mchain_t create_mchain(environment_t &env, const mchain_params_t ¶ms)
Create message chain.
mbox_t create_mbox(environment_t &env)
Create local anonymous mbox.
mbox_t create_mbox(environment_t &env, nonempty_name_t mbox_name)
Create local named mbox.
mbox_id_t allocate_mbox_id() noexcept
Allocate an ID for a new custom mbox or mchain.
mbox_core_stats_t query_stats()
Get statistics for run-time monitoring.
Base class for a mbox for the case when message delivery tracing is enabled.
A class for the name of mbox_namespace.
Parameters for message chain.
Interface of holder of message tracer and message trace filter objects.
A class for the name which cannot be empty.
Helper class for indication of long-lived reference via its type.
#define SO_5_THROW_EXCEPTION(error_code, desc)
Some reusable and low-level classes/functions which can be used in public header files.
std::unique_ptr< abstract_message_box_t > make_actual_mbox(outliving_reference_t< so_5::msg_tracing::holder_t > msg_tracing_stuff, A &&... args)
Implementation details for MPMC mboxes.
Various helpers for message delivery tracing mechanism.
Details of SObjectizer run-time implementations.
Various properties and parameters of message chains.
Public part of message delivery tracing mechanism.
Private part of message limit implementation.
message_delivery_mode_t
Possible modes of message/signal delivery.
mbox_type_t
Type of the message box.
Full name for a named mbox.
A coolection of data required for local mbox implementation.
messages_table_t m_subscribers
Map of subscribers to messages.
data_t(mbox_id_t id, environment_t &env)
environment_t & m_env
Environment for which the mbox is created.
default_rw_spinlock_t m_lock
Object lock.
const mbox_id_t m_id
ID of this mbox.
static constexpr const std::size_t switch_to_vector
static constexpr const std::size_t switch_to_map
Predicate to be used for comparing keys in subscriber map.
bool operator()(abstract_message_sink_t *a, abstract_message_sink_t *b) const noexcept
Predicate to be used for searching information in the vector.
bool operator()(const subscribers_vector_item_t &a, const subscribers_vector_item_t &b) const noexcept
Information about one subscriber to be stored in a vector.
subscription_info_with_sink_t m_info
Information about the subscription.
subscribers_vector_item_t(abstract_message_sink_t &sink_as_key)
abstract_message_sink_t * m_sink_as_key
Pointer to sink that has to be used as search key.
subscribers_vector_item_t(abstract_message_sink_t &sink_as_key, subscription_info_with_sink_t info)
The normal initializing constructor.
Statistics from mbox_core for run-time monitoring.
Base class for a mbox for the case when message delivery tracing is disabled.