SObjectizer 5.8
Loading...
Searching...
No Matches
local_mbox.hpp
Go to the documentation of this file.
1/*
2 SObjectizer 5.
3*/
4
5/*!
6 \file
7 \brief A local mbox definition.
8*/
9
10#pragma once
11
12#include <map>
13#include <vector>
14
15#include <so_5/types.hpp>
16#include <so_5/exception.hpp>
17
18#include <so_5/spinlocks.hpp>
19
20#include <so_5/msg_tracing.hpp>
21
22#include <so_5/mbox.hpp>
23#include <so_5/enveloped_msg.hpp>
24
25#include <so_5/impl/local_mbox_basic_subscription_info.hpp>
26
27#include <so_5/impl/msg_tracing_helpers.hpp>
28
29#include <so_5/details/invoke_noexcept_code.hpp>
30
31namespace so_5
32{
33
34namespace impl
35{
36
38{
39
40//
41// subscriber_adaptive_container_t
42//
43/*!
44 * \since
45 * v.5.5.12
46 *
47 * \brief A special container for holding subscriber_info objects.
48 *
49 * \note Uses std::vector as a storage for small amount of
50 * subscriber_infos and std::map for large amount.
51 */
53{
54 /*!
55 * \brief Information about one subscriber to be stored in a vector.
56 *
57 * It's necessary to have a pointer to message sink that will be
58 * used as a search key. Such a pointer from m_info field can't be
59 * used because it will be set to nullptr when agent drops the
60 * subscription but keeps a delivery filter.
61 */
63 {
64 //! Pointer to sink that has to be used as search key.
65 /*!
66 * \attention
67 * It's must not be nullptr!
68 */
70
71 //! Information about the subscription.
73
74 //! Special constructor for cases when item is created for searching
75 //! information in the vector.
77 abstract_message_sink_t & sink_as_key )
78 : m_sink_as_key{ std::addressof(sink_as_key) }
79 {}
80
81 //! The normal initializing constructor.
83 abstract_message_sink_t & sink_as_key,
85 : m_sink_as_key{ std::addressof(sink_as_key) }
86 , m_info{ std::move(info) }
87 {}
88 };
89
90 /*!
91 * \brief Predicate to be used for searching information in the vector.
92 */
94 {
95 [[nodiscard]]
96 bool
105 };
106
107 /*!
108 * \brief Predicate to be used for comparing keys in subscriber map.
109 */
111 {
112 [[nodiscard]]
113 bool
119 };
120
121 using vector_type = std::vector< subscribers_vector_item_t >;
122 using vector_iterator_type = vector_type::iterator;
123 using const_vector_iterator_type = vector_type::const_iterator;
124
125 using map_type = std::map<
129 >;
130 using map_iterator_type = map_type::iterator;
131 using const_map_iterator_type = map_type::const_iterator;
132
133 enum class storage_type { vector, map };
134
135 // NOTE! This is just arbitrary values.
136 // There were no any benchmarks to prove that those values are useful.
138 {
139 static constexpr const std::size_t switch_to_vector = 16;
140 static constexpr const std::size_t switch_to_map = 32;
141 };
142
143 //! The current storage type to be used by container.
145
146 //! Container for small amount of subscriber_infos.
147 vector_type m_vector;
148 //! Container for large amount of subscriber_infos.
149 map_type m_map;
150
151public :
152 //! Iterator type.
154 {
156
158 vector_iterator_type m_it_v;
159 map_iterator_type m_it_m;
160
161 public :
162 iterator( vector_iterator_type it_v )
164 , m_it_v{ std::move(it_v) }
165 {}
166 iterator( map_iterator_type it_m )
168 , m_it_m{ std::move(it_m) }
169 {}
170
173 {
175 return m_it_v->m_info;
176 else
177 return m_it_m->second;
178 }
179
182 {
183 return std::addressof(**this);
184 }
185
186 iterator &
188 {
190 ++m_it_v;
191 else
192 ++m_it_m;
193
194 return *this;
195 }
196
198 operator++(int)
199 {
201 {
202 iterator r{ *this };
203 ++m_it_v;
204 return r;
205 }
206 else
207 {
208 iterator r{ *this };
209 ++m_it_m;
210 return r;
211 }
212 }
213
214 bool
215 operator==( const iterator & o ) const
216 {
218 return m_it_v == o.m_it_v;
219 else
220 return m_it_m == o.m_it_m;
221 }
222
223 bool
224 operator!=( const iterator & o ) const
225 {
226 return !( *this == o );
227 }
228 };
229
230 //! Const iterator type.
232 {
234 const_vector_iterator_type m_it_v;
235 const_map_iterator_type m_it_m;
236
237 public :
238 const_iterator( const_vector_iterator_type it_v )
240 , m_it_v{ std::move(it_v) }
241 {}
242 const_iterator( const_map_iterator_type it_m )
244 , m_it_m{ std::move(it_m) }
245 {}
246
248 operator*() const
249 {
251 return m_it_v->m_info;
252 else
253 return m_it_m->second;
254 }
255
257 operator->() const
258 {
259 return std::addressof(**this);
260 }
261
264 {
266 ++m_it_v;
267 else
268 ++m_it_m;
269
270 return *this;
271 }
272
274 operator++(int)
275 {
277 {
278 const_iterator r{ *this };
279 ++m_it_v;
280 return r;
281 }
282 else
283 {
284 const_iterator r{ *this };
285 ++m_it_m;
286 return r;
287 }
288 }
289
290 bool
291 operator==( const const_iterator & o ) const
292 {
294 return m_it_v == o.m_it_v;
295 else
296 return m_it_m == o.m_it_m;
297 }
298
299 bool
300 operator!=( const const_iterator & o ) const
301 {
302 return !( *this == o );
303 }
304 };
305
306private :
307 //! Is vector used as a storage.
308 bool
310
311 //! Insertion of new item to vector.
312 void
314 abstract_message_sink_t & sink_as_key,
316 {
318 sink_as_key,
319 std::move(info)
320 };
321 const auto insertion_place = std::lower_bound(
322 m_vector.begin(),
323 m_vector.end(),
324 new_item,
326 m_vector.insert( insertion_place, std::move(new_item) );
327 }
328
329 //! Insertion of new item to map.
330 void
332 abstract_message_sink_t & sink_as_key,
334 {
335 m_map.emplace( std::addressof(sink_as_key), std::move(info) );
336 }
337
338 //! Switching storage from vector to map.
339 void
341 {
342 // All exceptions will be ignored.
343 // It is because an exception can be thrown on stages 1-2,
344 // but not on stage 3.
345 try
346 {
347 // Stage 1. New containers.
348 vector_type empty_vector;
349 map_type new_storage;
350
351 // Stage 2. Copying of items from the old container to new one.
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 );
355 } );
356
357 // No exceptions expected here.
359 [&]() {
360 swap( m_map, new_storage );
361 swap( m_vector, empty_vector );
363 } );
364 }
365 catch( ... )
366 {}
367 }
368
369 //! Switching storage from map to vector.
370 void
372 {
373 // All exceptions will be ignored.
374 // It is because an exception can be thrown on stages 1-2-3,
375 // but not on stage 4.
376 try
377 {
378 // Stage 1. New containers to swap values with old containers.
379 // An exception could be thrown in the constructors.
380 map_type empty_map;
381 vector_type new_storage;
382
383 // Stage 2. Preallocate necessary space in the new vector.
384 // An exception can be thrown here.
385 new_storage.reserve( m_map.size() );
386
387 // Stage 3. Copy items from old map to the new vector.
388 // We do not expect exceptions here at v.5.5.12, but
389 // the situation can change in the future versions.
390
391 // Use the fact that items in map is already ordered.
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 );
395 } );
396
397 // Stage 4. Swapping.
398 // No exceptions expected here.
400 [&]() {
401 swap( m_vector, new_storage );
402 swap( m_map, empty_map );
404 } );
405 }
406 catch(...)
407 {}
408 }
409
412 {
413 subscribers_vector_item_t info{ subscriber };
414 auto pos = std::lower_bound(
415 m_vector.begin(),
416 m_vector.end(),
417 info,
419 if( pos != m_vector.end()
420 && pos->m_sink_as_key == std::addressof(subscriber) )
421 return iterator{ pos };
422 else
423 return iterator{ m_vector.end() };
424 }
425
428 {
429 return iterator{ m_map.find( std::addressof(subscriber) ) };
430 }
431
432public :
433 //! Default constructor.
436 //! Copy constructor.
443 //! Move constructor.
445 subscriber_adaptive_container_t && o ) noexcept
447 , m_vector( std::move( o.m_vector ) )
448 , m_map( std::move( o.m_map ) )
449 {
450 // Other object is now empty.
451 // It must use vector as a storage.
453 }
454
455 friend void
459 {
460 using std::swap;
461 swap( a.m_storage, b.m_storage );
462 swap( a.m_vector, b.m_vector );
463 swap( a.m_map, b.m_map );
464 }
465
466 //! Copy operator.
469 {
471 swap( *this, tmp );
472 return *this;
473 }
474
475 //! Move operator.
478 {
479 subscriber_adaptive_container_t tmp{ std::move(o) };
480 swap( *this, tmp );
481 return *this;
482 }
483
484 void
486 abstract_message_sink_t & sink_as_key,
488 {
489 if( is_vector() )
490 {
493 }
494
495 if( is_vector() )
496 insert_to_vector( sink_as_key, std::move( info ) );
497 else
498 insert_to_map( sink_as_key, std::move( info ) );
499 }
500
501 template< typename... Args >
502 void
503 emplace( abstract_message_sink_t & sink_as_key, Args &&... args )
504 {
507 }
508
509 void
510 erase( const iterator & it )
511 {
512 if( is_vector() )
513 m_vector.erase( it.m_it_v );
514 else
515 {
516 m_map.erase( it.m_it_m );
517
518 // May be it is a time for switching to smaller storage?
521 }
522 }
523
526 {
527 if( is_vector() )
528 return find_in_vector( subscriber );
529 else
530 return find_in_map( subscriber );
531 }
532
535 {
536 if( is_vector() )
537 return iterator{ m_vector.begin() };
538 else
539 return iterator{ m_map.begin() };
540 }
541
544 {
545 if( is_vector() )
546 return iterator{ m_vector.end() };
547 else
548 return iterator{ m_map.end() };
549 }
550
552 begin() const
553 {
554 if( is_vector() )
555 return const_iterator{ m_vector.begin() };
556 else
557 return const_iterator{ m_map.begin() };
558 }
559
561 end() const
562 {
563 if( is_vector() )
564 return const_iterator{ m_vector.end() };
565 else
566 return const_iterator{ m_map.end() };
567 }
568
569 bool
570 empty() const
571 {
572 if( is_vector() )
573 return m_vector.empty();
574 else
575 return m_map.empty();
576 }
577
578 std::size_t
579 size() const
580 {
581 if( is_vector() )
582 return m_vector.size();
583 else
584 return m_map.size();
585 }
586};
587
588//
589// data_t
590//
591
592/*!
593 * \since
594 * v.5.5.9
595 *
596 * \brief A coolection of data required for local mbox implementation.
597 */
598struct data_t
599 {
600 data_t( mbox_id_t id, environment_t & env )
601 : m_id{ id }
602 , m_env{ env }
603 {}
604
605 //! ID of this mbox.
606 const mbox_id_t m_id;
607
608 //! Environment for which the mbox is created.
610
611 //! Object lock.
612 default_rw_spinlock_t m_lock;
613
614 /*!
615 * \since
616 * v.5.4.0
617 *
618 * \brief Map from message type to subscribers.
619 */
620 using messages_table_t = std::map<
621 std::type_index,
623
624 //! Map of subscribers to messages.
625 messages_table_t m_subscribers;
626 };
627
628} /* namespace local_mbox_details */
629
630//
631// local_mbox_template
632//
633
634//! A template with implementation of local mbox.
635/*!
636 * \since
637 * v.5.5.9
638 *
639 * \tparam Tracing_Base base class with implementation of message
640 * delivery tracing methods.
641 */
642template< typename Tracing_Base >
645 , private local_mbox_details::data_t
646 , private Tracing_Base
647 {
648 public:
649 template< typename... Tracing_Args >
651 //! ID of this mbox.
652 mbox_id_t id,
653 //! Environment for which the mbox is created.
654 environment_t & env,
655 //! Optional parameters for Tracing_Base's constructor.
656 Tracing_Args &&... args )
657 : local_mbox_details::data_t{ id, env }
658 , Tracing_Base{ std::forward< Tracing_Args >(args)... }
659 {}
660
661 mbox_id_t
662 id() const override
663 {
664 return m_id;
665 }
666
667 void
669 const std::type_index & type_wrapper,
670 abstract_message_sink_t & subscriber ) override
671 {
672 insert_or_modify_subscriber(
673 type_wrapper,
674 subscriber,
675 [&] {
677 subscriber
678 };
679 },
681 info.set_sink( subscriber );
682 } );
683 }
684
685 void
687 const std::type_index & type_wrapper,
688 abstract_message_sink_t & subscriber ) noexcept override
689 {
690 modify_and_remove_subscriber_if_needed(
691 type_wrapper,
692 subscriber,
694 info.drop_sink();
695 } );
696 }
697
698 std::string
699 query_name() const override
700 {
701 std::ostringstream s;
702 s << "<mbox:type=MPMC:id=" << m_id << ">";
703
704 return s.str();
705 }
706
708 type() const override
709 {
711 }
712
713 void
715 message_delivery_mode_t delivery_mode,
716 const std::type_index & msg_type,
717 const message_ref_t & message,
718 unsigned int redirection_deep ) override
719 {
720 typename Tracing_Base::deliver_op_tracer tracer{
721 *this, // as Tracing_base
722 *this, // as abstract_message_box_t
723 "deliver_message",
724 delivery_mode,
725 msg_type,
726 message,
727 redirection_deep };
728
729 ensure_immutable_message( msg_type, message );
730
732 tracer,
733 delivery_mode,
734 msg_type,
735 message,
736 redirection_deep );
737 }
738
739 void
741 const std::type_index & msg_type,
742 const delivery_filter_t & filter,
743 abstract_message_sink_t & subscriber ) override
744 {
745 insert_or_modify_subscriber(
746 msg_type,
747 subscriber,
748 [&] {
750 filter
751 };
752 },
754 info.set_filter( filter );
755 } );
756 }
757
758 void
760 const std::type_index & msg_type,
761 abstract_message_sink_t & subscriber ) noexcept override
762 {
763 modify_and_remove_subscriber_if_needed(
764 msg_type,
765 subscriber,
767 info.drop_filter();
768 } );
769 }
770
772 environment() const noexcept override
773 {
774 return m_env;
775 }
776
777 private :
778 template< typename Info_Maker, typename Info_Changer >
779 void
781 const std::type_index & type_wrapper,
782 abstract_message_sink_t & subscriber,
783 Info_Maker maker,
784 Info_Changer changer )
785 {
786 std::unique_lock< default_rw_spinlock_t > lock( m_lock );
787
788 auto it = m_subscribers.find( type_wrapper );
789 if( it == m_subscribers.end() )
790 {
791 // There isn't such message type yet.
793 container.insert( subscriber, maker() );
794
795 m_subscribers.emplace( type_wrapper, std::move( container ) );
796 }
797 else
798 {
799 auto & sinks = it->second;
800
801 auto pos = sinks.find( subscriber );
802 if( pos != sinks.end() )
803 {
804 // Agent is already in subscribers list.
805 // But its state must be updated.
806 changer( *pos );
807 }
808 else
809 // There is no subscriber in the container.
810 // It must be added.
811 sinks.insert( subscriber, maker() );
812 }
813 }
814
815 template< typename Info_Changer >
816 void
818 const std::type_index & type_wrapper,
819 abstract_message_sink_t & subscriber,
820 Info_Changer changer )
821 {
822 std::unique_lock< default_rw_spinlock_t > lock( m_lock );
823
824 auto it = m_subscribers.find( type_wrapper );
825 if( it != m_subscribers.end() )
826 {
827 auto & sinks = it->second;
828
829 auto pos = sinks.find( subscriber );
830 if( pos != sinks.end() )
831 {
832 // Subscriber is found and must be modified.
833 changer( *pos );
834
835 // If info about subscriber becomes empty after modification
836 // then subscriber info must be removed.
837 if( pos->empty() )
838 sinks.erase( pos );
839 }
840
841 if( sinks.empty() )
842 m_subscribers.erase( it );
843 }
844 }
845
846 void
848 typename Tracing_Base::deliver_op_tracer const & tracer,
849 message_delivery_mode_t delivery_mode,
850 const std::type_index & msg_type,
851 const message_ref_t & message,
852 unsigned int redirection_deep )
853 {
854 read_lock_guard_t< default_rw_spinlock_t > lock( m_lock );
855
856 auto it = m_subscribers.find( msg_type );
857 if( it != m_subscribers.end() )
858 {
859 for( const auto & a : it->second )
861 a,
862 tracer,
863 delivery_mode,
864 msg_type,
865 message,
866 redirection_deep );
867 }
868 else
869 tracer.no_subscribers();
870 }
871
872 void
874 const local_mbox_details::subscription_info_with_sink_t & subscriber_info,
875 typename Tracing_Base::deliver_op_tracer const & tracer,
876 message_delivery_mode_t delivery_mode,
877 const std::type_index & msg_type,
878 const message_ref_t & message,
879 unsigned int redirection_deep ) const
880 {
881 const auto delivery_status =
882 subscriber_info.must_be_delivered(
883 message,
884 []( const message_ref_t & m ) -> message_t & {
885 return *m;
886 } );
887
888 if( delivery_possibility_t::must_be_delivered == delivery_status )
889 {
890 subscriber_info.sink_reference().push_event(
891 this->m_id,
892 delivery_mode,
893 msg_type,
894 message,
895 redirection_deep,
896 tracer.overlimit_tracer() );
897 }
898 else
899 tracer.message_rejected(
900 subscriber_info.sink_pointer(), delivery_status );
901 }
902
903 /*!
904 * \brief Ensures that message is an immutable message.
905 *
906 * Checks mutability flag and throws an exception if message is
907 * a mutable one.
908 *
909 * \since
910 * v.5.5.19
911 */
912 void
914 const std::type_index & msg_type,
915 const message_ref_t & what ) const
916 {
921 "an attempt to deliver mutable message via MPMC mbox"
922 ", msg_type=" + std::string(msg_type.name()) );
923 }
924 };
925
926/*!
927 * \since
928 * v.5.5.9
929 *
930 * \brief Alias for local mbox without message delivery tracing.
931 */
932using local_mbox_without_tracing =
934
935/*!
936 * \since
937 * v.5.5.9
938 *
939 * \brief Alias for local mbox with message delivery tracing.
940 */
941using local_mbox_with_tracing =
943
944} /* namespace impl */
945
946} /* namespace so_5 */
Interface for message sink.
static bool special_sink_ptr_compare(const abstract_message_sink_t *a, const abstract_message_sink_t *b) noexcept
virtual void push_event(mbox_id_t mbox_id, message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const message_ref_t &message, unsigned int redirection_deep, const message_limit::impl::action_msg_tracer_t *tracer)=0
Get a message and push it to the appropriate destination.
A base class for agents.
Definition agent.hpp:673
Interface for creator of new mbox in OOP style.
virtual mbox_t create(const mbox_creation_data_t &data)=0
Creation of custom mbox.
An interface of delivery filter object.
Definition mbox.hpp:62
SObjectizer Environment.
A special container for holding subscriber_info objects.
subscriber_adaptive_container_t(const subscriber_adaptive_container_t &o)
Copy constructor.
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
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)
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.
An information block about one subscription to one message type with presence of message_sink.
void set_filter(const delivery_filter_t &filter)
Set the delivery filter for the subscriber.
abstract_message_sink_t & sink_reference() const noexcept
Get a reference to the subscribed sink.
abstract_message_sink_t * sink_pointer() const noexcept
Get a pointer to the subscribed sink.
void set_sink(abstract_message_sink_t &sink)
Inform about addition of a subscription.
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.
named_mboxes_dictionary_t m_named_mboxes_dictionary
Named mboxes.
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.
outliving_reference_t< so_5::msg_tracing::holder_t > m_msg_tracing_stuff
Data related to message delivery tracing.
mbox_core_t(outliving_reference_t< so_5::msg_tracing::holder_t > msg_tracing_stuff)
Definition mbox_core.cpp:27
std::mutex m_dictionary_lock
Named mbox map's lock.
mbox_t create_custom_mbox(environment_t &env, ::so_5::custom_mbox_details::creator_iface_t &creator)
Create a custom mbox.
std::atomic< mbox_id_t > m_mbox_id_counter
A counter for mbox ID generation.
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 &params)
Create message chain.
mbox_t create_mbox(environment_t &env)
Create local anonymous mbox.
Definition mbox_core.cpp:35
mbox_t create_mbox(environment_t &env, nonempty_name_t mbox_name)
Create local named mbox.
Definition mbox_core.cpp:46
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.
named_local_mbox_t(full_named_mbox_id_t full_name, const mbox_t &mbox, impl::mbox_core_t &mbox_core)
intrusive_ptr_t(T *obj) noexcept
Constructor for a raw pointer.
intrusive_ptr_t & operator=(intrusive_ptr_t &&o) noexcept
Move operator.
T & operator*() const noexcept
A class for the name of mbox_namespace.
std::string_view query_name() const noexcept(noexcept(std::string_view{m_name}))
Get the value.
Parameters for message chain.
Definition mchain.hpp:729
const mchain_props::capacity_t & capacity() const
Get chain's capacity and related params.
Definition mchain.hpp:757
memory_usage_t memory_usage() const
Memory allocation type for size-limited chain.
Definition mchain.hpp:332
bool unlimited() const
Is message chain have no size limit?
Definition mchain.hpp:318
Implementation of demands queue for size-limited message chain with dynamically allocated storage.
Implementation of demands queue for size-limited message chain with preallocated storage.
Implementation of demands queue for size-unlimited message chain.
A base class for agent messages.
Definition message.hpp:47
friend message_mutability_t message_mutability(const intrusive_ptr_t< message_t > &what) noexcept
Helper method for safe get of message mutability flag.
Definition message.hpp:74
Interface of holder of message tracer and message trace filter objects.
virtual bool is_msg_tracing_enabled() const noexcept=0
Is message tracing enabled?
A class for the name which cannot be empty.
std::string giveout_value() noexcept(noexcept(std::string{ std::move(m_nonempty_name) }))
Get the value away from the object.
Helper class for indication of long-lived reference via its type.
Definition outliving.hpp:98
T & get() const noexcept
outliving_reference_t(outliving_reference_t const &o) noexcept
Scoped guard for shared locks.
#define SO_5_THROW_EXCEPTION(error_code, desc)
Definition exception.hpp:74
Some reusable and low-level classes/functions which can be used in public header files.
auto invoke_noexcept_code(L lambda) noexcept -> decltype(lambda())
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.
Definition agent.cpp:780
mchain_t make_mchain(outliving_reference_t< so_5::msg_tracing::holder_t > tracer, const mchain_params_t &params, A &&... args)
Helper function for creation of a new mchain with respect to message tracing.
std::string default_global_mbox_namespace()
Helper function that returns name of the default global namespace for named mboxes.
Implementation details.
Definition mchain.hpp:37
Various properties and parameters of message chains.
Definition mchain.hpp:28
memory_usage_t
Memory allocation for storage for size-limited chains.
Definition mchain.hpp:182
@ dynamic
Storage can be allocated and deallocated dynamically.
Public part of message delivery tracing mechanism.
Private part of message limit implementation.
Definition agent.cpp:33
const int rc_nullptr_as_result_of_user_mbox_factory
nullptr returned by user-provided mbox factory.
Definition ret_code.hpp:468
message_delivery_mode_t
Possible modes of message/signal delivery.
Definition types.hpp:172
mbox_type_t
Type of the message box.
Definition mbox.hpp:163
message_mutability_t
A enum with variants of message mutability or immutability.
Definition types.hpp:94
delivery_possibility_t
Result of checking delivery posibility.
Definition mbox.hpp:39
const int rc_mutable_msg_cannot_be_delivered_via_mpmc_mbox
An attempt to deliver mutable message via MPMC mbox.
Definition ret_code.hpp:234
outliving_reference_t< T > outliving_mutable(T &r)
Make outliving_reference wrapper for mutable reference.
Full name for a named mbox.
Definition mbox_core.hpp:69
full_named_mbox_id_t(std::string mbox_namespace, std::string mbox_name)
Initializing constructor.
Definition mbox_core.hpp:86
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.
bool operator()(abstract_message_sink_t *a, abstract_message_sink_t *b) const noexcept
bool operator()(const subscribers_vector_item_t &a, const subscribers_vector_item_t &b) const noexcept
subscription_info_with_sink_t m_info
Information about the subscription.
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.
Definition mbox_core.hpp:49
mbox_t m_mbox
Real mbox for that name.
unsigned int m_external_ref_count
Reference count by external mbox_refs.
Base class for a mbox for the case when message delivery tracing is disabled.
An information which is necessary for creation of a new mbox.
mbox_creation_data_t(outliving_reference_t< environment_t > env, mbox_id_t id, outliving_reference_t< msg_tracing::holder_t > tracer)
Initializing constructor.