SObjectizer  5.8
Loading...
Searching...
No Matches
environment.hpp
Go to the documentation of this file.
1/*
2 SObjectizer 5.
3*/
4
5/*!
6 \file
7 \brief SObjectizer Environment definition.
8*/
9
10#pragma once
11
12#include <so_5/compiler_features.hpp>
13#include <so_5/coop.hpp>
14#include <so_5/coop_listener.hpp>
15#include <so_5/custom_mbox.hpp>
16#include <so_5/declspec.hpp>
17#include <so_5/disp_binder.hpp>
18#include <so_5/environment_infrastructure.hpp>
19#include <so_5/error_logger.hpp>
20#include <so_5/event_exception_logger.hpp>
21#include <so_5/event_queue_hook.hpp>
22#include <so_5/exception.hpp>
23#include <so_5/mbox.hpp>
24#include <so_5/mbox_namespace_name.hpp>
25#include <so_5/mchain.hpp>
26#include <so_5/message.hpp>
27#include <so_5/msg_tracing.hpp>
28#include <so_5/nonempty_name.hpp>
29#include <so_5/queue_locks_defaults_manager.hpp>
30#include <so_5/so_layer.hpp>
31#include <so_5/stop_guard.hpp>
32#include <so_5/subscription_storage_fwd.hpp>
33#include <so_5/timers.hpp>
34
35#include <so_5/stats/controller.hpp>
36#include <so_5/stats/repository.hpp>
37
38#include <so_5/disp/one_thread/params.hpp>
39#include <so_5/disp/nef_one_thread/params.hpp>
40#include <so_5/disp/abstract_work_thread.hpp>
41
42#include <chrono>
43#include <functional>
44#include <memory>
45#include <type_traits>
46#include <variant>
47
48#if defined( SO_5_MSVC )
49 #pragma warning(push)
50 #pragma warning(disable: 4251)
51#endif
52
53namespace so_5
54{
55
56namespace low_level_api
57{
58
60 {
61 //! Message type.
63 //! Message to be sent after timeout.
64 const message_ref_t & m_msg;
65 //! Mbox to which message will be delivered.
66 const mbox_t & m_mbox;
67 //! Timeout before the first delivery.
69 //! Period of the delivery repetition for periodic messages.
71 };
72
74 {
75 //! Message type.
77 //! Message to be sent after timeout.
78 const message_ref_t & m_msg;
79 //! Mbox to which message will be delivered.
80 const mbox_t & m_mbox;
81 //! Timeout before the delivery.
83 };
84
85} /* namespace low_level_api */
86
87//
88// environment_params_t
89//
90
91//! Parameters for the SObjectizer Environment initialization.
92/*!
93 * This class is used for setting SObjectizer Parameters.
94 *
95 * \see http://www.parashift.com/c++-faq/named-parameter-idiom.html
96 */
98{
99 public:
100 /*!
101 * \brief A sum type for holding parameters for the default disp.
102 *
103 * \since v.5.8.0
104 */
108 >;
109
110 /*!
111 * \brief Constructor.
112 *
113 * Sets default values for parameters.
114 */
116 /*!
117 * \brief Move constructor.
118 *
119 * \since v.5.2.3
120 */
123
124 /*!
125 * \brief Move operator.
126 *
127 * \since v.5.2.3
128 */
130 operator=( environment_params_t && other ) noexcept;
131
132 /*!
133 * \brief Swap operation.
134 *
135 * \since v.5.2.3
136 */
137 friend SO_5_FUNC void
139
140 //! Set the timer_thread factory.
141 /*!
142 * If \a factory is a null then the default timer thread
143 * will be used.
144 */
147 //! timer_thread factory to be used.
148 so_5::timer_thread_factory_t factory );
149
150 //! Add an additional layer to the SObjectizer Environment.
151 /*!
152 * If this layer is already added it will be replaced by \a layer_ptr.
153 *
154 * The method distinguishes layers from each other by the type SO_LAYER.
155 */
156 template< class SO_Layer >
159 //! A layer to be added.
160 std::unique_ptr< SO_Layer > layer_ptr )
161 {
162 if( layer_ptr.get() )
163 {
165
166 add_layer(
167 std::type_index( typeid( SO_Layer ) ),
168 std::move( ptr ) );
169 }
170
171 return *this;
172 }
173
174 //! Set cooperation listener object.
177 coop_listener_unique_ptr_t coop_listener );
178
179 //! Set exception logger object.
182 event_exception_logger_unique_ptr_t logger );
183
184 /*!
185 * \name Exception reaction flag management methods.
186 * \{
187 */
188 /*!
189 * \brief Get exception reaction flag value.
190 *
191 * \note
192 * This method is noexcept since v.5.8.0.
193 *
194 * \since v.5.3.0
195 */
197 exception_reaction() const noexcept
198 {
200 }
201
202 /*!
203 * \brief Set exception reaction flag value.
204 *
205 * Usage example:
206 * \code
207 * so_5::launch([](so_5::environment_t & env) {...},
208 * [](so_5::environment_params_t & params) {
209 * params.exception_reaction(so_5::exception_reaction_t::shutdown_sobjectizer_on_exception);
210 * ...
211 * });
212 * \endcode
213 *
214 * \note
215 * This method is noexcept since v.5.8.0.
216 *
217 * \since v.5.3.0
218 */
221 {
222 m_exception_reaction = value;
223 return *this;
224 }
225 /*!
226 * \}
227 */
228
229 /*!
230 * \brief Do not shutdown SO Environment when it is becomes empty.
231 *
232 * \par Description
233 * Since v.5.4.0 SO Environment checks count of live cooperations
234 * after every cooperation deregistration. If there is no more
235 * live cooperations then SO Environment will be shutted down.
236 * If it is not appropriate then this method must be called.
237 * It disables autoshutdown of SO Environment. Event if there is
238 * no more live cooperations SO Environment will work until
239 * explicit call to environment_t::stop() method.
240 *
241 * \since v.5.4.0
242 */
245 {
247 return *this;
248 }
249
250 /*!
251 * \brief Is autoshutdown disabled?
252 *
253 * \see disable_autoshutdown()
254 *
255 * \since v.5.4.0
256 */
257 [[nodiscard]]
258 bool
260 {
262 }
263
264 /*!
265 * \brief Set error logger for the environment.
266 *
267 * \since v.5.5.0
268 */
270 error_logger( error_logger_shptr_t logger )
271 {
272 m_error_logger = std::move(logger);
273 return *this;
274 }
275
276 /*!
277 * \brief Set message delivery tracer for the environment.
278 *
279 * Usage example:
280 * \code
281 * so_5::launch( [](so_5::environment_t & env) { ... },
282 * [](so_5::environment_params_t & params) {
283 * params.message_delivery_tracer( so_5::msg_tracing::std_cout_tracer() );
284 * ...
285 * } );
286 * \endcode
287 *
288 * \since v.5.5.9
289 */
291 message_delivery_tracer( so_5::msg_tracing::tracer_unique_ptr_t tracer )
292 {
293 m_message_delivery_tracer = std::move( tracer );
294 return *this;
295 }
296
297 /*!
298 * \brief Set message tracer filter for the environment.
299 *
300 * \since v.5.5.22
301 */
304 so_5::msg_tracing::filter_shptr_t filter )
305 {
306 m_message_delivery_tracer_filter = std::move( filter );
307 return *this;
308 }
309
310 /*!
311 * \brief Set parameters for a case when one_thread-disp
312 * must be used as the default dispatcher.
313 *
314 * \par Usage example:
315 \code
316 so_5::launch( []( so_5::environment_t & env ) { ... },
317 []( so_5::environment_params_t & env_params ) {
318 using namespace so_5::disp::one_thread;
319 // Event queue for the default dispatcher must use mutex as lock.
320 env_params.default_disp_params( disp_params_t{}.tune_queue_params(
321 []( queue_traits::queue_params_t & queue_params ) {
322 queue_params.lock_factory( queue_traits::simple_lock_factory() );
323 } ) );
324 } );
325 \endcode
326 *
327 * \note
328 * If some parameters have already been set, the old parameters will be
329 * replaced by new ones.
330 *
331 * \since v.5.5.10
332 */
335 {
336 m_default_disp_params = std::move(params);
337 return *this;
338 }
339
340 /*!
341 * \brief Set parameters for a case when
342 * nef_one_thread-disp must be used as the default dispatcher.
343 *
344 * \par Usage example:
345 \code
346 so_5::launch( []( so_5::environment_t & env ) { ... },
347 []( so_5::environment_params_t & env_params ) {
348 using namespace so_5::disp::nef_one_thread;
349 // Event queue for the default dispatcher must use mutex as lock.
350 env_params.default_disp_params( disp_params_t{}.tune_queue_params(
351 []( queue_traits::queue_params_t & queue_params ) {
352 queue_params.lock_factory( queue_traits::simple_lock_factory() );
353 } ) );
354 } );
355 \endcode
356 *
357 * \note
358 * If some parameters have already been set, the old parameters will be
359 * replaced by new ones.
360 *
361 * \since v.5.8.0
362 */
365 {
366 m_default_disp_params = std::move(params);
367 return *this;
368 }
369
370 /*!
371 * \brief Get the parameters for the default dispatcher.
372 *
373 * \attention
374 * The returned reference will be invalidated by any subsequent
375 * calls to default_disp_params-setters.
376 *
377 * \note
378 * Since v.5.8.0 it returns a sum type with parameters for different
379 * types of dispatchers. Therefore, the returned value has to be examined
380 * accordingly, for example:
381 * \code
382 * so_5::environment_params_t & params = ...
383 * const auto & disp_params = params.default_disp_params();
384 * if( const auto * one_thread =
385 * std::get_if< so_5::disp::one_thread::disp_params_t >( &disp_params ) )
386 * {
387 * ... // Handling.
388 * }
389 * else if( const auto * nef_one_thread =
390 * std::get_if< so_5::disp::nef_one_thread::disp_params_t >( &disp_params ) )
391 * {
392 * ... // Handling.
393 * }
394 * \endcode
395 *
396 * \since v.5.5.10
397 */
400 {
401 return m_default_disp_params;
402 }
403
404 /*!
405 * \brief Set activity tracking flag for the whole SObjectizer Environment.
406 *
407 * \since v.5.5.18
408 */
416
417 /*!
418 * \brief Get activity tracking flag for the whole SObjectizer Environment.
419 *
420 * \since v.5.5.18
421 */
427
428 //! Helper for turning work thread activity tracking on.
429 /*!
430 * \since v.5.5.18
431 */
438
439 //! Helper for turning work thread activity tracking off.
440 /*!
441 * \since v.5.5.18
442 */
449
450 //! Set manager for queue locks defaults.
451 /*!
452 * \since v.5.5.18
453 */
456 queue_locks_defaults_manager_unique_ptr_t manager )
457 {
458 m_queue_locks_defaults_manager = std::move(manager);
459 return *this;
460 }
461
462 //! Get the current environment infrastructure factory.
463 /*!
464 * \since v.5.5.19
465 */
468 {
469 return m_infrastructure_factory;
470 }
471
472 //! Set new environment infrastructure factory.
473 /*!
474 * Usage example:
475 * \code
476 * so_5::launch( []( so_5::environment_t & env ) {
477 * ... // Some initial actions.
478 * },
479 * []( so_5::environment_params_t & params ) {
480 * // Set infrastructure factory to make simple not-thread-safe
481 * // single-threaded infrastructure.
482 * params.infrastructure_factory(
483 * so_5::env_infrastructures::simple_not_mtsafe::factory() );
484 * } );
485 * \endcode
486 *
487 * \since v.5.5.19
488 */
491 environment_infrastructure_factory_t factory )
492 {
493 m_infrastructure_factory = std::move(factory);
494 return *this;
495 }
496
497 /*!
498 * \brief Set event_queue_hook object.
499 *
500 * Since v.5.5.24 it is possible to use special event_queue_hook
501 * object. If it is used it should be set for SObjectizer
502 * Environment before the Environment will be started. This method
503 * allows to specify event_queue_hook object for a new Environment
504 * object.
505 *
506 * Usage example:
507 * \code
508 * so_5::launch(
509 * [](so_5::environment_t & env) {...}, // Some stating actions.
510 * [](so_5::environment_params_t & params) {
511 * // Set my own event_queue hook object.
512 * so_5::make_event_queue_hook<my_hook>(
513 * // Object is created dynamically and should be
514 * // destroyed the normal way.
515 * so_5::event_queue_hook_t::default_deleter,
516 * arg1, arg3, arg3 // and all other arguments for my_hook's constructor.
517 * );
518 * });
519 * \endcode
520 *
521 * \note
522 * The previous event_queue_hook object (if it was set earlier)
523 * will just be dropped.
524 *
525 * \since v.5.5.24
526 */
527 void
529 event_queue_hook_unique_ptr_t hook )
530 {
531 m_event_queue_hook = std::move(hook);
532 }
533
534 /*!
535 * \brief Set work thread factory to be used by default.
536 *
537 * Since v.5.7.3 it's possible to use custom worker threads instead of
538 * standard ones provided by SObjectizer. To do so it's required to
539 * provide an appropriate worker thread factory. It can be done by
540 * specifying a factory in parameters for a dispatcher. Or it can be done
541 * globally for the whole SObjectizer's Environment by this method.
542 *
543 * This method sets a global factory that will be used by default. It
544 * means that:
545 *
546 * - the global factory won't be used if there is a factory in
547 * dispatcher's parameters (in that case dispatcher's factory has
548 * higher priority and the default factory is ignored);
549 * - the global factory will be used if there is no factory specified in
550 * dispatcher's parameters;
551 * - the global factory will be used for the default one_thread dispatcher
552 * created by default multi-thread environment infrastructure.
553 *
554 * Usage example:
555 * \code
556 * class my_thread_factory final : public so_5::disp::abstract_work_thread_factory_t
557 * {
558 * ...
559 * };
560 * ...
561 * so_5::launch( [](so_5::environment_t & env) {
562 * env.introduce_coop( [](so_5::coop_t & coop) {
563 * // This agent will be bound to the default dispatcher.
564 * // Worker thread for the default dispatcher will be provided
565 * // by default factory.
566 * coop.make_agent<my_agent>(...);
567 *
568 * // This agent will be bound to an instance of new one_thread
569 * // dispatcher. A worker thread for that new dispatcher will
570 * // be provided by the default factory.
571 * coop.make_agent_with_binder<my_agent>(
572 * so_5::disp::one_thread::make_dispatcher(coop.environment()).binder(),
573 * ...);
574 *
575 * // This dispatcher will use another own instance of
576 * // thread factory.
577 * auto tp_disp = so_5::disp::thread_pool::make_dispatcher(
578 * coop.environment(),
579 * "my_pool_disp",
580 * so_5::disp::thread_pool::disp_params_t{}
581 * .thread_count(10)
582 * .work_thread_factory(std::make_shared<my_thread_factory>(...)) );
583 * // This agent will be bound to the new thread_pool dispatcher
584 * // and will work on a thread provided by a separate thread factory.
585 * coop.make_agent_with_binder<my_agent>(tp_disp.binder());
586 * } );
587 * ...
588 * },
589 * [](so_5::environment_params_t & params) {
590 * params.work_thread_factory( std::make_shared<my_thread_factory>(...) );
591 * } );
592 * \endcode
593 *
594 * \since v.5.7.3
595 */
598 so_5::disp::abstract_work_thread_factory_shptr_t factory )
599 {
600 m_work_thread_factory = std::move(factory);
601 return *this;
602 }
603
604 /*!
605 * \brief Set subscription storage factory to be used by default.
606 *
607 * Usage example:
608 *
609 * \code
610 * so_5::launch( [](so_5::environment_t & env) {...},
611 * [](so_5::environment_params_t & params) {
612 * params.default_subscription_storage_factory(
613 * so_5::flat_set_based_subscription_storage_factory(32u) );
614 * } );
615 * \endcode
616 *
617 * \note
618 * The \a factory can be null (empty). This can be useful if there is a need
619 * to drop the previous value. For example:
620 * \code
621 * void tune_env_params(so_5::environment_params_t & params) {
622 * ... // Some settings.
623 * params.default_subscription_storage_factory(
624 * so_5::flat_set_based_subscription_storage_factory(32u));
625 * ... // Some more settings.
626 * }
627 * ...
628 * so_5::launch( [](so_5::environment_t & env) {...},
629 * [](so_5::environment_params_t & params) {
630 * // The main settings.
631 * tune_env_params(params);
632 *
633 * #if !defined(NDEBUG)
634 * // Have to drop some settings in the Debug mode.
635 * params.default_subscription_storage_factory({});
636 * #endif
637 * } );
638 * \endcode
639 *
640 * \since v.5.8.2
641 */
644 subscription_storage_factory_t factory )
645 {
646 m_default_subscription_storage_factory = std::move(factory);
647 return *this;
648 }
649
650 /*!
651 * \brief Get the current default subscription storage factory.
652 *
653 * \note
654 * This can be null (empty factory) if the factory isn't set
655 * explicitly.
656 *
657 * \since v.5.8.2
658 */
661 {
662 return m_default_subscription_storage_factory;
663 }
664
665 /*!
666 * \name Methods for internal use only.
667 * \{
668 */
669 //! Get map of default SObjectizer's layers.
670 [[nodiscard]]
673 {
674 return std::move( m_so_layers );
675 }
676
677 //! Get cooperation listener.
680 {
681 return std::move( m_coop_listener );
682 }
683
684 //! Get exception logger.
687 {
688 return std::move( m_event_exception_logger );
689 }
690
691 //! Get the timer_thread factory.
694 {
695 return std::move( m_timer_thread_factory );
696 }
697
698 //! Get error logger for the environment.
701 {
702 return m_error_logger;
703 }
704
705 /*!
706 * \brief Get message delivery tracer for the environment.
707 *
708 * \since v.5.5.9
709 */
712 {
713 return std::move( m_message_delivery_tracer );
714 }
715
716 /*!
717 * \brief Get message delivery tracer filter for the environment.
718 *
719 * \since v.5.5.22
720 */
721 so_5::msg_tracing::filter_shptr_t
723 {
724 return std::move( m_message_delivery_tracer_filter );
725 }
726
727 //! Take out queue locks defaults manager.
728 /*!
729 * \since v.5.5.18
730 */
733 {
734 return std::move( m_queue_locks_defaults_manager );
735 }
736
737 //! Take out event_queue_hook object.
738 /*!
739 * \since v.5.5.24
740 */
743 {
744 return std::move( m_event_queue_hook );
745 }
746
747 //! Take out work_thread_factory object.
748 /*!
749 * \since v.5.7.3
750 */
753 {
754 return std::move( m_work_thread_factory );
755 }
756 /*!
757 * \}
758 */
759
760 private:
761 //! Add an additional layer.
762 /*!
763 * If this layer is already added it will be replaced by \a layer_ptr.
764 *
765 * The method distinguishes layers from each other by the type SO_LAYER.
766 */
767 void
768 add_layer(
769 //! Type identification for layer.
770 const std::type_index & type,
771 //! A layer to be added.
772 layer_unique_ptr_t layer_ptr );
773
774 //! Timer thread factory.
776
777 //! Additional layers.
779
780 //! Cooperation listener.
782
783 //! Exception logger.
785
786 /*!
787 * \brief Exception reaction flag for the whole SO Environment.
788 *
789 * \since v.5.3.0
790 */
792
793 /*!
794 * \brief Is autoshutdown when there is no more cooperation disabled?
795 *
796 * \see disable_autoshutdown()
797 *
798 * \since v.5.4.0
799 */
801
802 /*!
803 * \brief Error logger for the environment.
804 *
805 * \since v.5.5.0
806 */
808
809 /*!
810 * \brief Tracer for message delivery.
811 *
812 * \since v.5.5.9
813 */
815
816 /*!
817 * \brief Message delivery tracer filter to be used with environment.
818 *
819 * \since v.5.5.22
820 */
822
823 /*!
824 * \brief Parameters for the default dispatcher.
825 *
826 * \since v.5.5.10
827 */
829
830 /*!
831 * \brief Work thread activity tracking for the whole Environment.
832 *
833 * \since v.5.5.18
834 */
836
837 /*!
838 * \brief Manager for defaults of queue locks.
839 *
840 * \since v.5.5.18
841 */
843
844 /*!
845 * \brief A factory for environment infrastructure entity.
846 *
847 * \since v.5.5.19
848 */
850
851 /*!
852 * \brief An event_queue_hook object.
853 *
854 * \note
855 * It can be a nullptr. It means that no event_queue_hook should
856 * be used.
857 *
858 * \since v.5.5.24
859 */
861
862 /*!
863 * \brief Global factory for work threads.
864 *
865 * \note
866 * It can be a nullptr. It means that standard work thread factory
867 * has to be used as the global factory.
868 *
869 * \since v.5.7.3
870 */
872
873 /*!
874 * \brief Default subscription storage factory.
875 *
876 * This factory will be used by default if a specific factory isn't
877 * set for agent explicitly.
878 *
879 * \note
880 * It can be a nullptr. It means that standard default subscription
881 * storage factory has to be used as the global factory.
882 *
883 * \since v.5.8.2
884 */
886};
887
888//
889// environment_t
890//
891
892//! SObjectizer Environment.
893/*!
894 * \section so_env__intro Basic information
895 *
896 * The SObjectizer Environment provides a basic infrastructure for
897 * the SObjectizer Run-Time execution.
898 *
899 * The main method of starting SObjectizer Environment creates a
900 * class derived from the environment_t and reimplementing the
901 * environment_t::init() method.
902 * This method should be used to define starting actions of
903 * application. For example first application cooperations can
904 * be registered here and starting messages can be sent to them.
905 *
906 * The SObjectizer Environment calls the environment_t::init() when
907 * the SObjectizer Run-Time is successfully started.
908 * If something happened during the Run-Time startup then
909 * the method init() will not be called.
910 *
911 * The SObjectizer Run-Time is started by the environment_t::run().
912 * This method blocks the caller thread until SObjectizer completely
913 * finished its work.
914 *
915 * The SObjectizer Run-Time is finished by the environment_t::stop().
916 * This method doesn't block the caller thread. Instead it sends a special
917 * shutdown signal to the Run-Time. The SObjectizer Run-Time then
918 * informs agents about this and waits finish of agents work.
919 * The SObjectizer Run-Time finishes if all agents are stopped and
920 * all cooperations are deregistered.
921 *
922 * Methods of the SObjectizer Environment can be splitted into the
923 * following groups:
924 * - working with mboxes;
925 * - working with dispatchers, exception loggers and handlers;
926 * - working with cooperations;
927 * - working with delayed and periodic messages;
928 * - working with additional layers;
929 * - initializing/running/stopping/waiting of the Run-Time.
930 *
931 * \section so_env__mbox_methods Methods for working with mboxes.
932 *
933 * SObjectizer Environment allows creation of named and anonymous mboxes.
934 * Syncronization objects for these mboxes can be obtained from
935 * common pools or assigned by a user during mbox creation.
936 *
937 * Mboxes are created by environment_t::create_mbox() methods.
938 * All these methods return the mbox_t which is a smart reference
939 * to the mbox.
940 *
941 * An anonymous mbox is automatically destroyed when the last reference to it is
942 * destroyed. So, to save the anonymous mbox, the mbox_ref from
943 * the create_mbox() should be stored somewhere.
944 *
945 * \section so_env__coop_methods Methods for working with cooperations.
946 *
947 * Cooperations can be created by environment_t::make_coop() methods.
948 *
949 * The method environment_t::register_coop() should be used for the
950 * cooperation registration.
951 *
952 * Method environment_t::deregister_coop() should be used for the
953 * cooperation deregistration.
954 */
956{
958
959 //! Auxiliary methods for getting reference to itself.
960 /*!
961 * Could be used in constructors without compiler warnings.
962 */
964 self_ref();
965
966 public:
967 explicit environment_t(
968 //! Initialization params.
969 environment_params_t && so_environment_params );
970
971 virtual ~environment_t();
972
973 environment_t( const environment_t & ) = delete;
975 operator=( const environment_t & ) = delete;
976
977 /*!
978 * \name Methods for working with mboxes.
979 * \{
980 */
981
982 //! Create an anonymous MPMC mbox.
983 /*!
984 * Usage example:
985 * \code
986 * class my_agent final : public so_5::agent_t {
987 * const so_5::mbox_t broadcast_mbox_;
988 * ...
989 * public:
990 * my_agent(context_t ctx)
991 * : so_5::agent_t{std::move(ctx)}
992 * , broadcast_mbox_{so_environment().create_mbox()}
993 * {}
994 * ...
995 * };
996 * \endcode
997 *
998 * \note always creates a new mbox.
999 */
1000 [[nodiscard]]
1001 mbox_t
1002 create_mbox();
1003
1004 //! Create named MPMC mbox.
1005 /*!
1006 * If \a mbox_name is unique then a new mbox will be created.
1007 * If not the reference to existing mbox will be returned.
1008 *
1009 * Usage example:
1010 * \code
1011 * class first_participant final : public so_5::agent_t {
1012 * const so_5::mbox_t broadcast_mbox_;
1013 * ...
1014 * public:
1015 * first_participant(context_t ctx)
1016 * : so_5::agent_t{std::move(ctx)}
1017 * , broadcast_mbox_{so_environment().create_mbox("message-board")}
1018 * {}
1019 * ...
1020 * };
1021 *
1022 * class second_participant final : public so_5::agent_t {
1023 * const so_5::mbox_t broadcast_mbox_;
1024 * ...
1025 * public:
1026 * second_participant(context_t ctx)
1027 * : so_5::agent_t{std::move(ctx)}
1028 * , broadcast_mbox_{so_environment().create_mbox("message-board")}
1029 * {}
1030 * ...
1031 * };
1032 * \endcode
1033 * In this example both agents will use the same mbox instance.
1034 *
1035 * \attention
1036 * Mboxes created by this method live in a separate namespace,
1037 * they are not mixed with named mboxes introduced via
1038 * introduce_named_mbox() method.
1039 */
1040 [[nodiscard]]
1041 mbox_t
1043 //! Mbox name.
1044 nonempty_name_t mbox_name );
1045
1046 /*!
1047 * \brief Introduce named mbox with user-provided factory.
1048 *
1049 * This method allows a user to create own named mbox.
1050 *
1051 * The create_mbox(nonempty_name_t) method always creates a standard
1052 * MPMC mbox. This isn't always desirable. For example, a user may want
1053 * to have a named unique_subscribers mbox. The introduce_named_mbox()
1054 * allows to achieve this:
1055 * \code
1056 * class first_participant final : public so_5::agent_t {
1057 * const so_5::mbox_t broadcast_mbox_;
1058 * ...
1059 * public:
1060 * first_participant(context_t ctx)
1061 * : so_5::agent_t{std::move(ctx)}
1062 * , broadcast_mbox_{so_environment().introduce_named_mbox(
1063 * so_5::mbox_namespace_name_t{"demo"},
1064 * "message-board",
1065 * [this]() { return so_5::make_unique_subscribers_mbox(so_environment()); } )
1066 * }
1067 * {}
1068 * ...
1069 * };
1070 *
1071 * class second_participant final : public so_5::agent_t {
1072 * const so_5::mbox_t broadcast_mbox_;
1073 * ...
1074 * public:
1075 * second_participant(context_t ctx)
1076 * : so_5::agent_t{std::move(ctx)}
1077 * , broadcast_mbox_{so_environment().introduce_named_mbox(
1078 * so_5::mbox_namespace_name_t{"demo"},
1079 * "message-board",
1080 * [this]() { return so_5::make_unique_subscribers_mbox(so_environment()); } )
1081 * }
1082 * {}
1083 * ...
1084 * };
1085 * \endcode
1086 *
1087 * The `introduce_named_mbox` work the following way:
1088 *
1089 *
1090 * - it checks for the existence of a mbox with the given name in the
1091 * specified namespace. If such a mbox is found it will be returned and
1092 * \a mbox_factory is not called;
1093 * - otherwise, the \a mbox_factory is called;
1094 * - after the completion of \a mbox_factory the existence of a mbox with
1095 * the given name is checked again;
1096 * - if there is still no such a mbox, then the mbox obtained from \a
1097 * mbox_factory is stored inside the SOEnv and returned as the result
1098 * of the `introduce_named_mbox` method;
1099 * - but if a mbox is found (it may have been created a little earlier by
1100 * a parallel call to the `introduce_named_mbox`), then the the value
1101 * returned by \a mbox_factory is discarded and the existing named mbox
1102 * is returned.
1103 *
1104 * It means then the \a mbox_factory is used if there is no a mbox with
1105 * the name specified yet. If such a mbox is already exists then the
1106 * already created mbox will be returned without calling \a mbox_factory.
1107 *
1108 * Note that named mboxes created by this method live in separate
1109 * namespaces and those namespaces aren't intersect with "the default"
1110 * namespace used by the create_mbox(nonempty_name_t) method. It means
1111 * that a user can create named mboxes with the same name in different
1112 * namespaces and they will be different mboxes:
1113 * \code
1114 * so_5::environment_t & env = ...;
1115 * auto std_mbox = env.create_mbox("alice");
1116 * auto my_mbox1 = env.introduce_named_mbox(
1117 * so_5::mbox_namespace_name_t{"a"},
1118 * "alice",
1119 * [&env]() { return env.create_mbox(); });
1120 * auto my_mbox2 = env.introduce_named_mbox(
1121 * so_5::mbox_namespace_name_t{"b"},
1122 * "alice",
1123 * [&env]() { return env.create_mbox(); });
1124 * // NOTE: it's just a reference to my_mbox2.
1125 * auto my_duplicate = env.introduce_named_mbox(
1126 * so_5::mbox_namespace_name_t{"b"},
1127 * "alice",
1128 * [&env]() { return env.create_mbox(); });
1129 *
1130 * assert(std_mbox->id() != my_mbox1->id());
1131 * assert(std_mbox->id() != my_mbox2->id());
1132 * assert(my_mbox1->id() != my_mbox2->id());
1133 * assert(my_mbox2->id() == my_duplicate->id());
1134 * \endcode
1135 *
1136 * \attention
1137 * The \a mbox_factory should return a valid so_5::mbox_t.
1138 * If \a mbox_factory returns empty so_5::mbox_t (nullptr), then
1139 * introduce_named_mbox() will throw an exception with
1140 * so_5::rc_nullptr_as_result_of_user_mbox_factory error code.
1141 * If \a mbox_factory can't create a valid so_5::mbox_t it
1142 * has to thrown a user-defined exception. This exception
1143 * will be let out from introduce_named_mbox(). For example:
1144 * \code
1145 * so_5::environment_t & env = ...;
1146 * try
1147 * {
1148 * auto mbox = env.introduce_named_mbox(
1149 * so_5::mbox_namespace_name_t{"b"},
1150 * "alice",
1151 * [&]() {
1152 * auto mbox = try_to_get_new_mbox();
1153 * if(!mbox)
1154 * throw my_exception{...};
1155 * return mbox;
1156 * });
1157 * }
1158 * catch( const my_exception & x ) { ... }
1159 * \endcode
1160 *
1161 * \note
1162 * If several parallel calls to introduce_named_mbox() with the same
1163 * parameters are made at the same time then \a mbox_factory can
1164 * be called several times (at most once for every introduce_named_mbox()
1165 * invocation). But only one result of those calls will be used,
1166 * all other returned values will be discarded.
1167 *
1168 * \attention
1169 * The \a mbox_factory can be called in parallel (so \a mbox_factory
1170 * should support this behavior).
1171 * The \a mbox_factory can safely call environment_t's methods
1172 * like create_mbox() and so on.
1173 *
1174 * \since v.5.8.0
1175 */
1176 [[nodiscard]]
1177 mbox_t
1179 //! Name of mbox_namespace for a new mbox.
1180 mbox_namespace_name_t mbox_namespace,
1181 //! Name for a new mbox.
1182 nonempty_name_t mbox_name,
1183 //! Factory for new mbox.
1184 const std::function< mbox_t() > & mbox_factory );
1185
1186 /*!
1187 * \}
1188 */
1189
1190 /*!
1191 * \name Method for working with message chains.
1192 * \{
1193 */
1194
1195 /*!
1196 * \brief Create message chain.
1197 *
1198 * \par Usage examples:
1199 \code
1200 so_5::environment_t & env = ...;
1201 // Create mchain with size-unlimited queue.
1202 auto ch1 = env.create_mchain(
1203 so_5::make_unlimited_mchain_params() );
1204 // Create mchain with size-limited queue without a timeout
1205 // on attempt to push another message to full mchain...
1206 auto ch2 = env.create_mchain(
1207 so_5::make_limited_without_waiting_mchain_params(
1208 // ...maximum size of the chain.
1209 100,
1210 // ...memory for chain will be allocated and deallocated dynamically...
1211 so_5::mchain_props::memory_usage_t::dynamic,
1212 // ...an exception will be thrown on overflow.
1213 so_5::mchain_props::overflow_reaction_t::throw_exception ) );
1214 // Create mchain with size-limited queue with a timeout for 200ms
1215 // on attempt to push another message to full mchain...
1216 auto ch3 = env.create_mchain(
1217 so_5::make_limited_with_waiting_mchain_params(
1218 // ...maximum size of the chain.
1219 100,
1220 // ...memory for chain will be preallocated...
1221 so_5::mchain_props::memory_usage_t::preallocated,
1222 // ...an oldest message from mchain will be removed on overflow...
1223 so_5::mchain_props::overflow_reaction_t::remove_oldest,
1224 // ...timeout for waiting on attempt to push a message into full mchain.
1225 std::chrono::milliseconds(200) ) );
1226 // Create size-unlimited mchain with custom notificator for
1227 // 'not_empty' situations.
1228 auto ch4 = env.create_mchain(
1229 so_5::make_unlimited_mchain_params().not_empty_notificator(
1230 [&] { some_widget.send_notify(); } ) );
1231 \endcode
1232 *
1233 * \since v.5.5.13
1234 */
1235 mchain_t
1237 //! Parameters for a new bag.
1238 const mchain_params_t & params );
1239 /*!
1240 * \}
1241 */
1242
1243 /*!
1244 * \name Method for working with dispatchers.
1245 * \{
1246 */
1247
1248 //! Set up an exception logger.
1249 void
1251 event_exception_logger_unique_ptr_t logger );
1252 /*!
1253 * \}
1254 */
1255
1256 /*!
1257 * \name Methods for working with cooperations.
1258 * \{
1259 */
1260
1261 //! Create a cooperation.
1262 /*!
1263 * Usage example:
1264 * \code
1265 * so_5::environmet_t & env = ...;
1266 * // A binder for the default dispatcher will be used.
1267 * auto coop = env.make_coop();
1268 * coop.make_agent<first_agent>(...);
1269 * coop.make_agent<second_agent>(...);
1270 * // Registration of the coop.
1271 * env.register_coop(std::move(coop));
1272 * \endcode
1273 *
1274 * \return A new cooperation. This cooperation
1275 * will use default dispatcher binders.
1276 *
1277 * \since v.5.6.0
1278 */
1279 [[nodiscard]]
1281 make_coop();
1282
1283 //! Create a cooperation with specified dispatcher binder.
1284 /*!
1285 * A binder \a disp_binder will be used for binding cooperation
1286 * agents to the dispatcher. This binder will be default binder for
1287 * this cooperation.
1288 *
1289 \code
1290 so_5::environment_t & so_env = ...;
1291 so_5::coop_unique_holder_t coop = so_env.make_coop(
1292 so_5::disp::active_group::make_dispatcher( so_env ).binder(
1293 "some_active_group" ) );
1294
1295 // That agent will be bound to the dispatcher "active_group"
1296 // and will be member of an active group with name
1297 // "some_active_group".
1298 coop->make_agent< a_some_agent_t >();
1299 \endcode
1300 *
1301 * \since v.5.6.0
1302 */
1303 [[nodiscard]]
1305 make_coop(
1306 //! A default binder for this cooperation.
1307 disp_binder_shptr_t disp_binder );
1308
1309 /*!
1310 * \brief Create a new cooperation that will be a child for
1311 * specified parent coop.
1312 *
1313 * The new cooperation will use the default dispatcher binder.
1314 *
1315 * Usage example:
1316 * \code
1317 * class parent_t final : public so_5::agent_t {
1318 * void on_some_event(mhood_t<some_message>) {
1319 * // We need to create a child coop.
1320 * auto coop = so_environment().make_coop(
1321 * // We as a parent.
1322 * so_coop());
1323 * ...
1324 * }
1325 * };
1326 * \endcode
1327 *
1328 * \since v.5.6.0
1329 */
1330 [[nodiscard]]
1332 make_coop(
1333 //! Parent coop.
1334 coop_handle_t parent );
1335
1336 /*!
1337 * \brief Create a new cooperation that will be a child for
1338 * specified parent coop.
1339 *
1340 * The new cooperation will use the specified dispatcher binder.
1341 *
1342 * Usage example:
1343 * \code
1344 * class parent_t final : public so_5::agent_t {
1345 * void on_some_event(mhood_t<some_message>) {
1346 * // We need to create a child coop.
1347 * auto coop = so_environment().make_coop(
1348 * // We as a parent.
1349 * so_coop(),
1350 * // The default dispatcher for the new coop.
1351 * so_5::disp::active_obj::make_dispatcher(
1352 * so_environment() ).binder() );
1353 * ...
1354 * }
1355 * };
1356 * \endcode
1357 *
1358 * \since v.5.6.0
1359 */
1360 [[nodiscard]]
1362 make_coop(
1363 //! Parent coop.
1364 coop_handle_t parent,
1365 //! A default binder for this cooperation.
1366 disp_binder_shptr_t disp_binder );
1367
1368 //! Register a cooperation.
1369 /*!
1370 * The cooperation registration includes following steps:
1371 *
1372 * - binding agents to the cooperation object;
1373 * - checking uniques of the cooperation name. The cooperation will
1374 * not be registered if its name isn't unique;
1375 * - agent_t::so_define_agent() will be called for each agent
1376 * in the cooperation;
1377 * - binding of each agent to the dispatcher.
1378 *
1379 * If all these actions are successful then the cooperation is
1380 * marked as registered.
1381 *
1382 * \par Usage examples
1383 *
1384 * Very simple case.
1385 * \code
1386 * so_5::environment_t & env = ...;
1387 *
1388 * auto simple_coop = env.make_coop();
1389 * simple_coop->make_agent<some_agent_type>(...);
1390 * env.register_coop(std::move(simple_coop));
1391 * \endcode
1392 *
1393 * More complex case with storing coop_handle and using it for
1394 * coop deregistration:
1395 * \code
1396 * so_5::environment_t & env = ...;
1397 * so_5::coop_handle_t coop_handle;
1398 *
1399 * auto simple_coop = env.make_coop();
1400 * simple_coop->make_agent<some_agent_type>(...);
1401 * coop_handle = env.register_coop(std::move(simple_coop));
1402 * ...
1403 * // Some time later.
1404 * env.deregister_coop(coop_handle, so_5::dereg_reason::normal);
1405 * \endcode
1406 *
1407 * A typical scenario for register_coop() when an instance of coop
1408 * is created by a separate function:
1409 * \code
1410 * [[nodiscard]] so_5::coop_unique_holder_t create_coop(
1411 * so_5::environment_t & env)
1412 * {
1413 * auto coop = env.make_coop();
1414 * coop->make_agent<some_agent_type>(...);
1415 * ... // Some other actions like creation of additional agents.
1416 *
1417 * // Now the coop can be returned back.
1418 * return coop;
1419 * }
1420 *
1421 * so_5::environment_t & env = ...;
1422 * ...
1423 * env.register_coop(create_coop(env));
1424 * \endcode
1425 */
1428 //! Cooperation to be registered.
1429 coop_unique_holder_t agent_coop );
1430
1431 /*!
1432 * \brief Register single agent as a cooperation.
1433 *
1434 * It is just a helper methods for convience.
1435 *
1436 * Usage sample:
1437 * \code
1438 std::unique_ptr< my_agent > a( new my_agent(...) );
1439 so_env.register_agent_as_coop( std::move(a) );
1440 * \endcode
1441 */
1442 template< class A >
1445 std::unique_ptr< A > agent )
1446 {
1447 auto coop = make_coop();
1448 coop->add_agent( std::move( agent ) );
1449 return register_coop( std::move( coop ) );
1450 }
1451
1452 /*!
1453 * \brief Register single agent as a cooperation with specified
1454 * dispatcher binder.
1455 *
1456 * It is just a helper methods for convience.
1457 *
1458 * Usage sample:
1459 * \code
1460 * so_5::environment_t & env = ...;
1461 * env.register_agent_as_coop(
1462 * std::make_unique<my_agent>(...),
1463 * so_5::disp::active_group::make_dispatcher(env)
1464 * .binder("some_active_group") );
1465 * \endcode
1466 *
1467 * \since v.5.2.1
1468 */
1469 template< class A >
1472 std::unique_ptr< A > agent,
1473 disp_binder_shptr_t disp_binder )
1474 {
1475 auto coop = make_coop( std::move( disp_binder ) );
1476 coop->add_agent( std::move( agent ) );
1477 return register_coop( std::move( coop ) );
1478 }
1479
1480 //! Deregister the cooperation.
1481 /*!
1482 * Method searches the cooperation within registered cooperations and if
1483 * it is found deregisters it.
1484 *
1485 * Deregistration can take some time.
1486 *
1487 * At first a special signal is sent to cooperation agents.
1488 * By receiving these signal agents stop receiving new messages.
1489 * When the local event queue for an agent becomes empty the
1490 * agent informs the cooperation about this. When the cooperation
1491 * receives all these signals from agents it informs
1492 * the SObjectizer Run-Time.
1493 *
1494 * Only after this the cooperation is deregistered on the special
1495 * context.
1496 *
1497 * After the cooperation deregistration agents are unbound from
1498 * dispatchers.
1499 *
1500 * Usage example:
1501 * \code
1502 * so_5::environment_t & env = ...;
1503 * so_5::coop_handle_t coop_handle;
1504 *
1505 * auto simple_coop = env.make_coop();
1506 * simple_coop->make_agent<some_agent_type>(...);
1507 * coop_handle = env.register_coop(std::move(simple_coop));
1508 * ...
1509 * // Some time later.
1510 * env.deregister_coop(coop_handle, so_5::dereg_reason::normal);
1511 * \endcode
1512 *
1513 * \note
1514 * This method is marked as noexcept because there is no way
1515 * to recover if any exception is raised here.
1516 *
1517 * \attention
1518 * It's safe to pass an empty coop_handle_t to deregister_coop().
1519 * It's also safe to pass a coop_handle of a coop that is already deregistered.
1520 * For example, this is not an error:
1521 * \code
1522 * class demo {
1523 * so_5::environment_t & m_env;
1524 * so_5::coop_handle_t m_child_coop;
1525 * ...
1526 * public:
1527 * demo(
1528 * so_5::environment_t & env,
1529 * so_5::coop_handle_t child_coop)
1530 * : m_env{env}
1531 * , m_child_coop{std::move(child_coop)}
1532 * {}
1533 *
1534 * ~demo() {
1535 * // Force the deregistration of the child coop.
1536 * // Don't care if drop_child() has already been called.
1537 * m_env.deregister_coop(m_child_coop, so_5::dereg_reason::normal);
1538 * }
1539 * ...
1540 * void drop_child() {
1541 * m_env.deregister_coop(m_child_coop, so_5::dereg_reason::normal);
1542 * }
1543 * };
1544 * ...
1545 * void some_action(so_5::environment_t & env) {
1546 * ...
1547 * coop_handle = env.register_coop(...);
1548 * demo holder{env, coop_handle};
1549 * ...
1550 * holder.drop_child(); // The first call to deregister_coop.
1551 * ...
1552 * } // Another call to deregister_coop in the destructor of demo object.
1553 * \endcode
1554 */
1555 void
1557 //! The coop to be deregistered.
1558 coop_handle_t coop,
1559 //! Deregistration reason.
1560 int reason ) noexcept
1561 {
1562 auto coop_shptr = low_level_api::to_shptr_noexcept( coop );
1563 if( coop_shptr )
1564 coop_shptr->deregister( reason );
1565 }
1566 /*!
1567 * \}
1568 */
1569
1570 /*!
1571 * \name Methods for working with layers.
1572 * \{
1573 */
1574
1575 //! Get access to the layer without raising exception if layer
1576 //! is not found.
1577 template< class SO_Layer >
1578 SO_Layer *
1580 {
1581 static_assert( std::is_base_of< layer_t, SO_Layer >::value,
1582 "SO_Layer must be derived from so_layer_t class" );
1583
1584 return dynamic_cast< SO_Layer * >(
1585 query_layer( std::type_index( typeid( SO_Layer ) ) ) );
1586 }
1587
1588 //! Get access to the layer with exception if layer is not found.
1589 template< class SO_Layer >
1590 SO_Layer *
1592 {
1594
1595 if( !layer )
1598 "layer does not exist" );
1599
1600 return layer;
1601 }
1602
1603 //! Add an additional layer.
1604 template< class SO_Layer >
1605 void
1607 std::unique_ptr< SO_Layer > layer_ptr )
1608 {
1610 std::type_index( typeid( SO_Layer ) ),
1612 }
1613 /*!
1614 * \}
1615 */
1616
1617 /*!
1618 * \name Methods for starting, initializing and stopping of the Run-Time.
1619 * \{
1620 */
1621
1622 //! Run the SObjectizer Run-Time.
1623 void
1624 run();
1625
1626 //! Initialization hook.
1627 /*!
1628 * \attention A hang inside of this method will prevent the Run-Time
1629 * from stopping. For example if a dialog with an application user
1630 * is performed inside init() then SObjectizer cannot finish
1631 * its work until this dialog is finished.
1632 */
1633 virtual void
1634 init() = 0;
1635
1636 //! Send a shutdown signal to the Run-Time.
1637 /*!
1638 * \note
1639 * This method is noexcept since v.5.8.0.
1640 */
1641 void
1642 stop() noexcept;
1643 /*!
1644 * \}
1645 */
1646
1647 /*!
1648 * \brief Call event exception logger for logging an exception.
1649 *
1650 * \note
1651 * Since v.5.6.0 this method is marked as noexcept.
1652 *
1653 * \since v.5.2.3
1654 */
1655 void
1657 //! Exception caught.
1658 const std::exception & event_exception,
1659 //! A cooperation to which agent is belong.
1660 const coop_handle_t & coop ) noexcept;
1661
1662 /*!
1663 * \brief An exception reaction for the whole SO Environment.
1664 *
1665 * \note
1666 * This method is noexcept since v.5.8.0.
1667 *
1668 * \since v.5.3.0
1669 */
1671 exception_reaction() const noexcept;
1672
1673 /*!
1674 * \brief Get the error_logger object.
1675 *
1676 * \since v.5.5.0
1677 */
1679 error_logger() const;
1680
1681 /*!
1682 * \brief Helper method for simplification of agents creation.
1683 *
1684 * \since v.5.5.4
1685 *
1686 * \note Creates an instance of agent of type \a Agent by using
1687 * environment_t::make_agent() template function and adds it to
1688 * the cooperation. Uses the fact that most agent types use reference
1689 * to the environment object as the first argument.
1690 *
1691 * \return unique pointer to the new agent.
1692 *
1693 * \tparam Agent type of agent to be created.
1694 * \tparam Args type of parameters list for agent constructor.
1695 *
1696 * \par Usage sample:
1697 \code
1698 so_5::environment_t & env = ...;
1699 // For the case of constructor like my_agent(environmen_t&).
1700 auto a1 = env.make_agent< my_agent >();
1701 // For the case of constructor like your_agent(environment_t&, std::string).
1702 auto a2 = env.make_agent< your_agent >( "hello" );
1703 // For the case of constructor like their_agent(environment_t&, std::string, mbox_t).
1704 auto a3 = env.make_agent< their_agent >( "bye", a2->so_direct_mbox() );
1705 \endcode
1706 */
1707 template< class Agent, typename... Args >
1708 std::unique_ptr< Agent >
1710 {
1711 return std::unique_ptr< Agent >(
1712 new Agent( *this, std::forward<Args>(args)... ) );
1713 }
1714
1715 /*!
1716 * \brief Access to controller of run-time monitoring.
1717 *
1718 * \since v.5.5.4
1719 */
1722
1723 /*!
1724 * \brief Access to repository of data sources for run-time monitoring.
1725 *
1726 * \since v.5.5.4
1727 */
1730
1731 /*!
1732 * \brief Access to the global work thread factory.
1733 *
1734 * \since v.5.7.3
1735 */
1736 [[nodiscard]]
1738 work_thread_factory() const noexcept;
1739
1740 /*!
1741 * \brief Helper method for simplification of cooperation creation
1742 * and registration.
1743 *
1744 * \return The value returned from lambda-function. Or void if
1745 * the lambda-function returns void.
1746 *
1747 * \since v.5.5.5
1748 *
1749 * \par Usage samples:
1750 \code
1751 // The default dispatcher will be used for binding.
1752 env.introduce_coop( []( so_5::coop_t & coop ) {
1753 coop.make_agent< first_agent >(...);
1754 coop.make_agent< second_agent >(...);
1755 });
1756
1757 // For the case when dispatcher binder is specified.
1758 env.introduce_coop(
1759 so_5::disp::active_obj::make_dispatcher( env ).binder(),
1760 []( so_5::coop_t & coop ) {
1761 coop.make_agent< first_agent >(...);
1762 coop.make_agent< second_agent >(...);
1763 } );
1764
1765 // Usage of return value from the lambda function.
1766 so_5::mbox_t mbox = env.introduce_coop( [](so_5::coop_t & coop) {
1767 auto * a = coop.make_agent< first_agent >(...);
1768 coop.make_agent< second_agent >(...);
1769
1770 return a->so_direct_mbox();
1771 });
1772 \endcode
1773 */
1774 template< typename... Args >
1775 decltype(auto)
1776 introduce_coop( Args &&... args );
1777
1778 /*!
1779 * \brief Get activity tracking flag for the whole SObjectizer Environment.
1780 *
1781 * \since v.5.5.18
1782 */
1785
1786 /*!
1787 * \brief Get binding to the default dispatcher.
1788 *
1789 * \note
1790 * This method is part of environment_t for possibility to
1791 * write custom implementations of environment_infrastructure_t.
1792 * Because of that this method can be changed or removed in
1793 * future versions of SObjectizer.
1794 *
1795 * \since v.5.5.19
1796 */
1799
1800 /*!
1801 * \brief Get autoshutdown_disabled flag.
1802 *
1803 * Autoshutdown feature is on by default. It can be turned off
1804 * in environment_params_t. This methods returns <i>true</i> if
1805 * autoshutdown is turned off.
1806 *
1807 * \since v.5.5.19
1808 */
1809 bool
1810 autoshutdown_disabled() const;
1811
1812 //! Schedule timer event.
1813 /*!
1814 * \attention
1815 * Values of \a pause and \a period should be non-negative.
1816 *
1817 * \note
1818 * This method is a part of low-level SObjectizer's API.
1819 * Because of that it can be changed or removed in some
1820 * future version of SObjectizer without prior notice.
1821 */
1824 //! Parameters for new timer.
1825 const low_level_api::schedule_timer_params_t params );
1826
1827 //! Schedule a single shot timer event.
1828 /*!
1829 * \attention
1830 * Value of \a pause should be non-negative.
1831 *
1832 * \note
1833 * This method is a part of low-level SObjectizer's API.
1834 * Because of that it can be changed or removed in some
1835 * future version of SObjectizer without prior notice.
1836 */
1837 void
1839 //! Parameters for new timer.
1840 const low_level_api::single_timer_params_t params );
1841
1842 //! Create a custom mbox.
1843 /*!
1844 * \tparam Lambda type of actual lambda with all creation actions.
1845 * The Lambda must be lambda-function or functional objects with
1846 * the following format:
1847 * \code
1848 * so_5::mbox_t lambda(const so_5::mbox_creation_data_t &);
1849 * \endcode
1850 *
1851 * \since v.5.5.19.2
1852 */
1853 template< typename Lambda >
1854 mbox_t
1855 make_custom_mbox( Lambda && lambda )
1856 {
1857 using namespace custom_mbox_details;
1858
1860 return do_make_custom_mbox( creator );
1861 }
1862
1863 /*!
1864 * \name Methods for working with stop_guards.
1865 * \{
1866 */
1867 //! Set up a new stop_guard.
1868 /*!
1869 * Usage examples:
1870 * \code
1871 * // Add a stop_guard.
1872 * // Note: an exception can be thrown if stop is in progress
1873 * class my_stop_guard
1874 * : public so_5::stop_guard_t
1875 * , public std::enable_shared_from_this< my_stop_guard >
1876 * {...};
1877 *
1878 * class my_agent : public so_5::agent_t
1879 * {
1880 * ...
1881 * void on_some_event()
1882 * {
1883 * // We need a stop_guard here.
1884 * m_my_guard = std::make_shared< my_stop_guard >(...);
1885 * so_environment().setup_stop_guard( m_my_guard );
1886 * }
1887 * private :
1888 * so_5::stop_guard_shptr_t m_my_guard;
1889 * };
1890 *
1891 * //
1892 * // Add a stop_guard without throwing an exception if stop is in progress
1893 * //
1894 * class my_stop_guard
1895 * : public so_5::stop_guard_t
1896 * , public std::enable_shared_from_this< my_stop_guard >
1897 * {...};
1898 *
1899 * class my_agent : public so_5::agent_t
1900 * {
1901 * ...
1902 * void on_some_event()
1903 * {
1904 * // We need a stop_guard here.
1905 * m_my_guard = std::make_shared< my_stop_guard >(...);
1906 * const auto r = so_environment().setup_stop_guard(
1907 * m_my_guard,
1908 * so_5::stop_guard_t::what_if_stop_in_progress_t::return_negative_result );
1909 * if( so_5::stop_guard_t::setup_result_t::stop_already_in_progress == r )
1910 * ... // handle error here.
1911 * }
1912 * private :
1913 * so_5::stop_guard_shptr_t m_my_guard;
1914 * };
1915 * \endcode
1916 *
1917 * \note
1918 * Uniqueness of stop_guard is not checked. It means that
1919 * it is possible to add the same stop_guard several times.
1920 * But it seems to be useless.
1921 *
1922 * \since v.5.5.19.2
1923 */
1926 //! Stop guard to be set.
1927 //! Should not be nullptr.
1928 stop_guard_shptr_t guard,
1929 //! What to do is the stop operation is already in progress?
1930 stop_guard_t::what_if_stop_in_progress_t reaction_on_stop_in_progress
1932
1933 //! Remove stop_guard and complete the stop operation if necessary.
1934 /*!
1935 * Every stop_guard which was added to the environment must be
1936 * explicitely removed from the environment. It is done by this method.
1937 * If there is no more stop_guard and the stop operation is in progress
1938 * then the environment will complete the stop operation.
1939 *
1940 * Usage examples:
1941 * \code
1942 * // Note: an exception can be thrown if stop is in progress
1943 * class my_stop_guard
1944 * : public so_5::stop_guard_t
1945 * , public std::enable_shared_from_this< my_stop_guard >
1946 * {...};
1947 *
1948 * class my_agent : public so_5::agent_t
1949 * {
1950 * ...
1951 * void on_some_event()
1952 * {
1953 * // We need a stop_guard here.
1954 * m_my_guard = std::make_shared< my_stop_guard >(...);
1955 * so_environment().setup_stop_guard( m_my_guard );
1956 * }
1957 *
1958 * void on_work_finished_signal()
1959 * {
1960 * // Stop_guard must be removed now.
1961 * so_environment().remove_stop_guard( m_my_guard );
1962 * }
1963 * private :
1964 * so_5::stop_guard_shptr_t m_my_guard;
1965 * };
1966 * \endcode
1967 *
1968 * \since v.5.5.19.2
1969 */
1970 void
1972 //! Stop guard to be removed.
1973 stop_guard_shptr_t guard );
1974 /*!
1975 * \}
1976 */
1977
1978 /*!
1979 * \name Methods for working with msg_tracing's filters.
1980 * \{
1981 */
1982 /*!
1983 * \brief Change the current msg_tracing's filter to a new one.
1984 *
1985 * Usage example:
1986 * \code
1987 * so_5::launch([](so_5::environment_t & env) {...},
1988 * [](so_5::environment_params_t & params) {
1989 * // Turn message delivery tracing on.
1990 * params.message_delivery_tracer(
1991 * so_5::msg_tracing::std_cout_tracer());
1992 * // Disable all trace messages.
1993 * // It is expected that trace filter will be changed in the future.
1994 * params.message_delivery_tracer_filter(
1995 * so_5::msg_tracing::make_disable_all_filter());
1996 * ...
1997 * } );
1998 * ...
1999 * void some_agent_t::turn_msg_tracing_on() {
2000 * // Remove trace filter. As result all trace messages will be printed.
2001 * so_environment().change_message_delivery_tracer_filter(
2002 * so_5::msg_tracing::no_filter());
2003 * ...
2004 * }
2005 * \endcode
2006 *
2007 * \note
2008 * It is possible that there are active calls to
2009 * so_5::msg_tracing::filter_t::filter() methods at the time of
2010 * invocation of change_message_delivery_tracer_filter(). In this
2011 * case all active calls will be completed with the previous
2012 * filter. This could lead to mixture of messages in the trace:
2013 * some of them will be enabled by old filter and some of them
2014 * will be enabled by new filter. And it is possible that
2015 * messages enabled by new filter will precede messages enabled
2016 * by old filter.
2017 *
2018 * \throw exception_t if message delivery tracing is disabled.
2019 *
2020 * \since v.5.5.22
2021 */
2022 void
2024 //! A new filter to be used.
2025 //! It can be an empty pointer. In this case all trace messages
2026 //! will be passed to tracer object.
2027 so_5::msg_tracing::filter_shptr_t filter );
2028 /*!
2029 * \}
2030 */
2031
2032 private:
2033 //! Access to an additional layer.
2034 layer_t *
2036 const std::type_index & type ) const;
2037
2038 //! Add an additional layer.
2039 void
2041 const std::type_index & type,
2042 const layer_ref_t & layer );
2043
2044 //! Remove an additional layer.
2045 void
2047 const std::type_index & type );
2048
2049 //! Actual creation of a custom mbox.
2050 /*!
2051 * \since v.5.5.19.2
2052 */
2053 mbox_t
2056
2057 struct internals_t;
2058
2059 //! SObjectizer Environment internals.
2061
2062 /*!
2063 * \name Implementation details related to run/stop functionality.
2064 * \{
2065 */
2066 /*!
2067 * \brief Run controller for run-time monitoring
2068 * and call next run stage.
2069 *
2070 * \since v.5.5.4
2071 */
2072 void
2074
2075 /*!
2076 * \brief Run layers and call next run stage.
2077 */
2078 void
2080
2081 /*!
2082 * \brief Launch environment infrastructure and wait for finish.
2083 *
2084 * \since v.5.5.19
2085 */
2086 void
2088 /*!
2089 * \}
2090 */
2091};
2092
2093namespace details
2094{
2095
2096/*!
2097 * \brief Helper class for building and registering new cooperation.
2098 *
2099 * \since v.5.5.5
2100 */
2102{
2103private :
2104 //! Environment for creation of cooperation.
2106 //! Optional parent coop.
2108
2109 template< typename Lambda >
2110 decltype(auto)
2112 disp_binder_shptr_t binder,
2113 Lambda && lambda )
2114 {
2115 const auto coop_maker = [this, b = std::move(binder)] {
2116 if( m_parent )
2117 return m_env.make_coop( m_parent, std::move(b) );
2118 else
2119 return m_env.make_coop( std::move(b) );
2120 };
2121
2122 auto coop = coop_maker();
2123
2124 using return_type = std::invoke_result_t<Lambda, so_5::coop_t &>;
2125
2126 if constexpr( std::is_void_v<return_type> )
2127 {
2128 lambda( *coop );
2129 m_env.register_coop( std::move( coop ) );
2130 }
2131 else if constexpr( std::is_reference_v<return_type> )
2132 {
2133 auto && ret_val = lambda( *coop );
2134 m_env.register_coop( std::move( coop ) );
2135
2136 return std::forward<decltype(ret_val)>(ret_val);
2137 }
2138 else
2139 {
2140 auto ret_val = lambda( *coop );
2141 m_env.register_coop( std::move( coop ) );
2142
2143 return ret_val;
2144 }
2145 }
2146
2147public :
2148 //! Constructor for the case of creation a cooperation without parent.
2150 : m_env{ env }
2151 {}
2152 //! Constructor for the case of creation a cooperation with parent.
2154 environment_t & env,
2155 coop_handle_t parent )
2156 : m_env{ env }
2157 , m_parent{ std::move(parent) }
2158 {}
2159
2160 /*!
2161 * For the case:
2162 * - default dispatcher is used.
2163 */
2164 template< typename L >
2165 decltype(auto)
2166 introduce( L && lambda )
2167 {
2168 return build_and_register_coop(
2169 m_env.so_make_default_disp_binder(),
2170 std::forward< L >( lambda ) );
2171 }
2172
2173 /*!
2174 * For the case:
2175 * - dispatcher builder is specified.
2176 */
2177 template< typename L >
2178 decltype(auto)
2179 introduce( disp_binder_shptr_t binder, L && lambda )
2180 {
2181 return build_and_register_coop(
2182 std::move( binder ),
2183 std::forward< L >( lambda ) );
2184 }
2185};
2186
2187} /* namespace details */
2188
2189template< typename... Args >
2190decltype(auto)
2192{
2193 details::introduce_coop_helper_t helper{ *this };
2194 return helper.introduce( std::forward< Args >( args )... );
2195}
2196
2197/*!
2198 * \brief A simple way for creating child cooperation.
2199 *
2200 * \since v.5.5.3
2201 *
2202 * \par Usage sample
2203 \code
2204 class owner : public so_5::agent_t
2205 {
2206 public :
2207 ...
2208 virtual void
2209 so_evt_start() override
2210 {
2211 auto child = so_5::create_child_coop( *this );
2212 child->make_agent< worker >();
2213 ...
2214 so_environment().register_coop( std::move( child ) );
2215 }
2216 };
2217 \endcode
2218 */
2219template< typename... Args >
2220[[nodiscard]]
2223 //! Owner of the cooperation.
2224 agent_t & owner,
2225 //! Arguments for the environment_t::make_coop() method.
2226 Args&&... args )
2227{
2229 owner.so_coop(),
2230 std::forward< Args >(args)... );
2231
2232 return coop;
2233}
2234
2235/*!
2236 * \brief A simple way for creating child cooperation when there is
2237 * a reference to the parent cooperation object.
2238 *
2239 * \since v.5.5.8
2240 *
2241 * \par Usage sample
2242 \code
2243 class parent final : public so_5::agent_t {
2244 void on_some_event(mhood_t<some_message>) {
2245 auto child = so_5::create_child_coop(
2246 // We as the parent coop.
2247 so_coop(),
2248 // The default binder for the new coop.
2249 so_5::disp::one_thread::make_dispatcher(
2250 so_environment().binder() ) );
2251 ...
2252 so_environment().register_coop( std::move(child) );
2253 }
2254 ...
2255 };
2256 \endcode
2257 */
2258template< typename... Args >
2259[[nodiscard]]
2262 //! Parent cooperation.
2263 coop_handle_t parent,
2264 //! Arguments for the environment_t::make_coop() method.
2265 Args&&... args )
2266{
2268 parent,
2269 std::forward< Args >(args)... );
2270}
2271
2272/*!
2273 * \brief A simple way for creating and registering child cooperation.
2274 *
2275 * \since v.5.5.5
2276 *
2277 * \par Usage sample
2278 \code
2279 class owner : public so_5::agent_t
2280 {
2281 public :
2282 ...
2283 virtual void
2284 so_evt_start() override
2285 {
2286 so_5::introduce_child_coop( *this, []( so_5::coop_t & coop ) {
2287 coop.make_agent< worker >();
2288 } );
2289 }
2290 };
2291 \endcode
2292
2293 * \note This function is just a tiny wrapper around
2294 * so_5::environment_t::introduce_coop() helper method. For more
2295 * examples with usage of introduce_coop() please see description of
2296 * that method.
2297 */
2298template< typename... Args >
2299decltype(auto)
2301 //! Owner of the cooperation.
2302 agent_t & owner,
2303 //! Arguments for the environment_t::introduce_coop() method.
2304 Args&&... args )
2305{
2306 return details::introduce_coop_helper_t{
2307 owner.so_environment(),
2308 owner.so_coop()
2309 }.introduce( std::forward< Args >(args)... );
2310}
2311
2312/*!
2313 * \brief A simple way for creating and registering child cooperation
2314 * when there is a reference to parent coop.
2315 *
2316 * \since v.5.5.8
2317 *
2318 * \par Usage sample
2319 \code
2320 class owner : public so_5::agent_t
2321 {
2322 public :
2323 ...
2324 virtual void
2325 so_evt_start() override
2326 {
2327 so_5::introduce_child_coop( so_coop(), []( so_5::coop_t & coop ) {
2328 coop.make_agent< worker >();
2329 } );
2330 }
2331 };
2332 \endcode
2333
2334 * \note This function is just a tiny wrapper around
2335 * so_5::environment_t::introduce_coop() helper method. For more
2336 * examples with usage of introduce_coop() please see description of
2337 * that method.
2338 */
2339template< typename... Args >
2340decltype(auto)
2342 //! Parent cooperation.
2343 coop_handle_t parent,
2344 //! Arguments for the environment_t::introduce_coop() method.
2345 Args&&... args )
2346{
2347 return details::introduce_coop_helper_t{
2348 low_level_api::to_shptr(parent)->environment(),
2349 parent
2350 }.introduce( std::forward< Args >(args)... );
2351}
2352
2353//
2354// make_default_disp_binder
2355//
2356/*!
2357 * \brief Create an instance of the default dispatcher binder.
2358 *
2359 * \note This function takes into account a possibility to have
2360 * different types of environment infrastructures (introduced in v.5.5.19)
2361 * and creates a default dispatcher binder with respect to the
2362 * actual environment infrastructure type.
2363 *
2364 * Usage example:
2365 * \code
2366 * so_5::launch( [](so_5::environment_t & env) {
2367 * env.introduce_coop(
2368 * // Agents from that coop will be bound to the default dispatcher.
2369 * so_5::make_default_disp_binder(env),
2370 * [](so_5::coop_t & coop) {
2371 * coop.make_agent<...>(...);
2372 * } );
2373 * } );
2374 * \endcode
2375 *
2376 * \since v.5.5.19
2377 */
2380 {
2381 return env.so_make_default_disp_binder();
2382 }
2383
2384namespace low_level_api
2385{
2386
2387//! Schedule periodic timer event.
2388/*!
2389 * \note
2390 * This function is a part of low-level SObjectizer's interface.
2391 * Because of that this function can be removed or changed in some
2392 * future version without prior notice.
2393 *
2394 * \attention
2395 * Values of \a pause and \a period should be non-negative.
2396 *
2397 * \since v.5.6.0
2398 */
2399[[nodiscard]] inline so_5::timer_id_t
2401 //! Message type for searching subscribers.
2402 const std::type_index & subscription_type,
2403 //! Message to be sent after timeout.
2404 message_ref_t msg,
2405 //! Mbox to which message will be delivered.
2406 const mbox_t & mbox,
2407 //! Timeout before the first delivery.
2408 std::chrono::steady_clock::duration pause,
2409 //! Period of the delivery repetition for periodic messages.
2410 /*!
2411 \note Value 0 indicates that it's not periodic message
2412 (will be delivered one time).
2413 */
2414 std::chrono::steady_clock::duration period )
2415{
2416 return mbox->environment().so_schedule_timer(
2417 schedule_timer_params_t{
2418 std::cref(subscription_type),
2419 std::cref(msg),
2420 std::cref(mbox),
2421 pause,
2422 period } );
2423}
2424
2425//! Schedule single timer event.
2426/*!
2427 * \note
2428 * This function is a part of low-level SObjectizer's interface.
2429 * Because of that this function can be removed or changed in some
2430 * future version without prior notice.
2431 *
2432 * \attention
2433 * Value \a period should be non-negative.
2434 *
2435 * \since v.5.6.0
2436 */
2437inline void
2439 //! Message type for searching subscribers.
2440 const std::type_index & subscription_type,
2441 //! Message to be sent after timeout.
2442 message_ref_t msg,
2443 //! Mbox to which message will be delivered.
2444 const mbox_t & mbox,
2445 //! Timeout before the delivery.
2446 std::chrono::steady_clock::duration pause )
2447{
2448 return mbox->environment().so_single_timer(
2449 single_timer_params_t{
2450 std::cref(subscription_type),
2451 std::cref(msg),
2452 std::cref(mbox),
2453 pause } );
2454}
2455
2456} /* namespace low_level_api */
2457
2458} /* namespace so_5 */
2459
2460#if defined( SO_5_MSVC )
2461 #pragma warning(pop)
2462#endif
virtual void unsubscribe_event_handler(const std::type_index &type_index, abstract_message_sink_t &subscriber) noexcept=0
Remove all message handlers.
virtual void subscribe_event_handler(const std::type_index &type_index, abstract_message_sink_t &subscriber)=0
Add the message handler.
virtual so_5::environment_t & environment() const noexcept=0
SObjectizer Environment for which the mbox is created.
abstract_message_box_t(const abstract_message_box_t &)=delete
virtual void drop_delivery_filter(const std::type_index &msg_type, abstract_message_sink_t &subscriber) noexcept=0
Removes delivery filter for message type and subscriber.
virtual void set_delivery_filter(const std::type_index &msg_type, const delivery_filter_t &filter, abstract_message_sink_t &subscriber)=0
Set a delivery filter for message type and subscriber.
virtual ~abstract_message_box_t() noexcept=default
virtual mbox_id_t id() const =0
Unique ID of this mbox.
virtual std::string query_name() const =0
Get the mbox name.
abstract_message_box_t & operator=(abstract_message_box_t &&)=delete
virtual 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)=0
Deliver message for all subscribers with respect to message limits.
abstract_message_box_t & operator=(const abstract_message_box_t &)=delete
virtual mbox_type_t type() const =0
Get the type of message box.
abstract_message_box_t(abstract_message_box_t &&)=delete
Interface for message sink.
abstract_message_sink_t & operator=(const abstract_message_sink_t &)=default
abstract_message_sink_t(const abstract_message_sink_t &)=default
abstract_message_sink_t(abstract_message_sink_t &&) noexcept=default
abstract_message_sink_t & operator=(abstract_message_sink_t &&) noexcept=default
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.
virtual priority_t sink_priority() const noexcept=0
Get the priority for the message sink.
virtual environment_t & environment() const noexcept=0
virtual ~abstract_message_sink_t() noexcept=default
Interface for holders of message_sink instances.
virtual const abstract_message_sink_t & sink() const noexcept=0
Get a const reference to the underlying message sink.
virtual abstract_message_sink_t & sink() noexcept=0
Get a reference to the underlying message sink.
virtual ~abstract_sink_owner_t() noexcept=default
A context for agent construction and tuning.
environment_t * m_env
SObjectizer Environment to work in.
agent_context_t(environment_t &env, agent_tuning_options_t options)
const agent_tuning_options_t & options() const
Read-only access to agent options.
agent_context_t(environment_t &env)
Constructor for the case when only environment available.
environment_t & environment() const
Access to SObjectizer Environment.
agent_tuning_options_t & options()
Read-Write access to agent options.
friend void swap(so_5::agent_context_t &a, so_5::agent_context_t &b) noexcept
Swap operation.
agent_tuning_options_t m_options
Options for agent tuning.
environment_t & env() const
Access to SObjectizer Environment.
Helper class for holding agent's identity (name or pointer).
std::string_view actual_name() const noexcept
Attempt to get an agent name.
friend std::ostream & operator<<(std::ostream &to, const agent_identity_t &what)
std::string to_string() const
Transform identity into a string.
agent_identity_t(std::string_view name) noexcept
Initializing constructor for case when agent has a user specified name.
bool has_actual_name() const noexcept
Does agent have an actual name?
value_t m_value
Agent's identity.
agent_identity_t(const agent_t *pointer) noexcept
Initializing constructor for case when agent has no user specified name.
Interface of the agent state listener.
virtual ~agent_state_listener_t() noexcept=default
agent_state_listener_t(const agent_state_listener_t &)=delete
agent_state_listener_t & operator=(const agent_state_listener_t &)=delete
virtual void changed(agent_t &agent, const state_t &state) noexcept=0
Hook method for state changes.
Type for holding information necessary for handling time limits for agent states.
Definition agent.hpp:3019
bool is_defined() const noexcept
Is the data for handling time limits defined?
Definition agent.cpp:692
A base class for agents.
Definition agent.hpp:673
void so_subscribe_deadletter_handler(const so_5::mbox_t &mbox, Event_Handler &&handler, thread_safety_t thread_safety=thread_safety_t::unsafe)
Create a subscription for deadletter handler for a specific message from a specific mbox.
Definition agent.hpp:2125
static demand_handler_pfn_t get_demand_handler_on_start_ptr() noexcept
Definition agent.cpp:1461
impl::state_listener_controller_t m_state_listener_controller
State listeners controller.
Definition agent.hpp:2854
decltype(auto) so_low_level_exec_as_event_handler(Lambda &&lambda) noexcept(noexcept(lambda()))
Helper method that allows to run a block of code as non-thread-safe event handler.
Definition agent.hpp:2675
static void process_enveloped_msg(current_thread_id_t working_thread_id, execution_demand_t &d, const impl::event_handler_data_t *handler_data)
Actual implementation of enveloped message handling.
Definition agent.cpp:1591
std::unique_ptr< impl::sinks_storage_t > m_message_sinks
Holder of message sinks for that agent.
Definition agent.hpp:2894
const state_t st_default
Definition agent.hpp:2819
void do_change_agent_state(const state_t &state_to_be_set)
Perform actual operations related to state switch.
Definition agent.cpp:1791
void so_drop_delivery_filter(const mbox_t &mbox) noexcept
Drop a delivery filter.
Definition agent.hpp:2576
void so_initiate_agent_definition()
A correct initiation of so_define_agent method call.
Definition agent.cpp:963
const agent_t * self_ptr() const
Get the raw pointer of itself.
Definition agent.hpp:834
void evt_state_time_limit(mhood_t< so_5::details::msg_state_timeout >)
Special event handler to process state time limits.
Definition agent.cpp:1945
so_5::current_thread_id_t m_working_thread_id
Working thread id.
Definition agent.hpp:2950
default_rw_spinlock_t m_event_queue_lock
Event queue operation protector.
Definition agent.hpp:2918
const name_for_agent_t m_name
Optional name for the agent.
Definition agent.hpp:2999
static const impl::event_handler_data_t * find_deadletter_handler(execution_demand_t &demand)
Search for event handler between deadletter handlers.
Definition agent.cpp:1781
static demand_handler_pfn_t get_demand_handler_on_message_ptr() noexcept
Definition agent.cpp:1526
bool is_agent_deactivated() const noexcept
Is agent already deactivated.
Definition agent.cpp:1907
void so_switch_to_awaiting_deregistration_state()
Switching agent to special state in case of unhandled exception.
Definition agent.cpp:881
const state_t & so_current_state() const
Access to the current agent state.
Definition agent.hpp:967
static void process_message(current_thread_id_t working_thread_id, execution_demand_t &d, thread_safety_t thread_safety, event_handler_method_t method)
Actual implementation of message handling.
Definition agent.cpp:1550
agent_ref_t create_ref()
Make an agent reference.
Definition agent.cpp:1150
void so_drop_deadletter_handler(const so_5::mbox_t &mbox)
Drops the subscription for deadletter handler.
Definition agent.hpp:2174
bool so_is_active_state(const state_t &state_to_check) const noexcept
Is a state activated?
Definition agent.cpp:844
void ensure_operation_is_on_working_thread(const char *operation_name) const
Enables operation only if it is performed on agent's working thread.
Definition agent.cpp:1639
static constexpr const state_t::history_t deep_history
Short alias for so_5::state_t::history_t::deep.
Definition agent.hpp:737
bool so_was_defined() const
Is method define_agent already called?
Definition agent.cpp:981
agent_status_t
Enumeration of possible agent statuses.
Definition agent.hpp:2834
@ shutdown_with_skipping_pending_demands
Agent was shutdown and all pending demands have to be skipped.
@ defined
Agent is defined.
@ state_switch_in_progress
State switch operation is in progress.
void destroy_all_subscriptions_and_filters() noexcept
Destroy all agent's subscriptions.
Definition agent.cpp:1143
void shutdown_agent() noexcept
Agent shutdown deriver.
Definition agent.cpp:1163
void ensure_binding_finished()
Ensures that all agents from cooperation are bound to dispatchers.
Definition agent.cpp:1452
coop_t * m_agent_coop
Agent is belong to this cooperation.
Definition agent.hpp:2953
disp_binder_shptr_t so_this_agent_disp_binder() const
Returns the dispatcher binder that is used for binding this agent.
Definition agent.hpp:2716
agent_status_t m_current_status
Current agent status.
Definition agent.hpp:2851
event_queue_t * m_event_queue
A pointer to event_queue.
Definition agent.hpp:2933
void so_set_delivery_filter(const mbox_t &mbox, Lambda &&lambda)
Set a delivery filter.
Definition agent.hpp:3577
virtual void so_define_agent()
Hook on define agent for SObjectizer.
Definition agent.cpp:975
void drop_all_delivery_filters() noexcept
Drops all delivery filters.
Definition agent.cpp:1664
disp_binder_shptr_t m_disp_binder
Binder for this agent.
Definition agent.hpp:2987
bool do_check_subscription_presence(const mbox_t &mbox, const std::type_index &msg_type, const state_t &target_state) const noexcept
Check the presence of a subscription.
Definition agent.cpp:1337
void do_state_switch(const state_t &state_to_be_set) noexcept
Actual action for switching agent state.
Definition agent.cpp:1832
std::unique_ptr< impl::delivery_filter_storage_t > m_delivery_filters
Delivery filters for that agents.
Definition agent.hpp:2962
void return_to_default_state_if_possible() noexcept
Return agent to the default state.
Definition agent.cpp:1895
subscription_bind_t so_subscribe_self()
Initiate subscription to agent's direct mbox.
Definition agent.hpp:1461
agent_t(environment_t &env)
Constructor.
Definition agent.cpp:775
void do_set_delivery_filter(const mbox_t &mbox, const std::type_index &msg_type, delivery_filter_unique_ptr_t filter)
Set a delivery filter.
Definition agent.cpp:1674
static void call_push_event(agent_t &agent, const message_limit::control_block_t *limit, mbox_id_t mbox_id, const std::type_index &msg_type, const message_ref_t &message)
Push an event to the agent's event queue.
Definition agent.hpp:1070
mbox_t so_make_new_direct_mbox()
Create a new direct mbox for that agent.
Definition agent.cpp:893
static execution_hint_t so_create_execution_hint(execution_demand_t &demand)
Create execution hint for the specified demand.
Definition agent.cpp:1035
void so_change_state(const state_t &new_state)
Change the current state of the agent.
Definition agent.cpp:936
void push_event(const message_limit::control_block_t *limit, mbox_id_t mbox_id, const std::type_index &msg_type, const message_ref_t &message)
Push event into the event queue.
Definition agent.cpp:1403
static custom_direct_mbox_factory_t custom_direct_mbox_factory(Lambda &&lambda)
Helper for creation a custom direct mbox factory.
Definition agent.hpp:1168
coop_handle_t so_coop() const
Get a handle of agent's coop.
Definition agent.cpp:994
void so_deregister_agent_coop_normally()
A helper method for deregistering agent's coop in case of normal deregistration.
Definition agent.cpp:1116
void do_drop_delivery_filter(const mbox_t &mbox, const std::type_index &msg_type) noexcept
Drop a delivery filter.
Definition agent.cpp:1702
virtual exception_reaction_t so_exception_reaction() const noexcept
A reaction from SObjectizer to an exception from agent's event.
Definition agent.cpp:871
void so_deactivate_agent()
Deactivate the agent.
Definition agent.cpp:945
disp_binder_shptr_t so_this_coop_disp_binder() const
Returns the dispatcher binder that is used as the default binder for the agent's coop.
Definition agent.cpp:1122
abstract_message_sink_t & detect_sink_for_message_type(const std::type_index &msg_type)
Helper function that returns a message sink to be used for subscriptions for specified message type.
Definition agent.cpp:1291
const demands_handling_on_dereg_t m_demands_handling_on_dereg
What to do with pending demands on deregistration.
Definition agent.hpp:3085
static void demand_handler_on_message(current_thread_id_t working_thread_id, execution_demand_t &d)
Calls event handler for message.
Definition agent.cpp:1509
static constexpr const state_t::history_t shallow_history
Short alias for so_5::state_t::history_t::shallow.
Definition agent.hpp:730
void so_drop_all_subscriptions_and_filters()
Dropping all agents subscriptions and filters.
Definition agent.cpp:954
virtual void so_evt_finish()
Hook of agent finish in SObjectizer.
Definition agent.cpp:838
static demand_handler_pfn_t get_demand_handler_on_finish_ptr() noexcept
Definition agent.cpp:1503
void so_add_nondestroyable_listener(agent_state_listener_t &state_listener)
Add a state listener to the agent.
Definition agent.cpp:853
static const impl::event_handler_data_t * handler_finder_msg_tracing_disabled(execution_demand_t &demand, const char *context_marker)
Handler finder for the case when message delivery tracing is disabled.
Definition agent.cpp:1713
const state_t * m_current_state_ptr
Current agent state.
Definition agent.hpp:2826
const mbox_t m_direct_mbox
A direct mbox for the agent.
Definition agent.hpp:2940
bool so_has_deadletter_handler(const so_5::mbox_t &mbox) const noexcept
Checks the presence of deadletter handler for a message of a specific type from a specific mbox.
Definition agent.hpp:2215
agent_t * self_ptr()
Definition agent.hpp:840
const priority_t m_priority
Priority of the agent.
Definition agent.hpp:2969
agent_identity_t so_agent_name() const noexcept
Get an optional name of the agent.
Definition agent.cpp:1134
static const impl::event_handler_data_t * handler_finder_msg_tracing_enabled(execution_demand_t &demand, const char *context_marker)
Handler finder for the case when message delivery tracing is enabled.
Definition agent.cpp:1726
void bind_to_coop(coop_t &coop)
Bind agent to the cooperation.
Definition agent.cpp:1157
static const impl::event_handler_data_t * find_event_handler_for_current_state(execution_demand_t &demand)
Actual search for event handler with respect to parent-child relationship between agent states.
Definition agent.cpp:1760
static void demand_handler_on_start(current_thread_id_t working_thread_id, execution_demand_t &d)
Calls so_evt_start method for agent.
Definition agent.cpp:1425
const mbox_t & so_direct_mbox() const
Get the agent's direct mbox.
Definition agent.cpp:887
impl::subscription_storage_unique_ptr_t m_subscriptions
All agent's subscriptions.
Definition agent.hpp:2881
void so_destroy_deadletter_subscription(const mbox_t &mbox, const std::type_index &msg_type)
Destroy a subscription for a deadletter handler.
Definition agent.cpp:1277
static void demand_handler_on_finish(current_thread_id_t working_thread_id, execution_demand_t &d)
Calls so_evt_finish method for agent.
Definition agent.cpp:1467
bool do_check_deadletter_presence(const mbox_t &mbox, const std::type_index &msg_type) const noexcept
Check the presence of a deadletter handler.
Definition agent.cpp:1347
void do_drop_subscription_for_all_states(const mbox_t &mbox, const std::type_index &msg_type)
Remove subscription for all states.
Definition agent.cpp:1322
agent_t(context_t ctx)
Constructor which simplifies agent construction with or without agent's tuning options.
Definition agent.cpp:788
static agent_tuning_options_t tuning_options()
Create tuning options object with default values.
Definition agent.hpp:1136
void so_add_destroyable_listener(agent_state_listener_unique_ptr_t state_listener)
Add a state listener to the agent.
Definition agent.cpp:862
environment_t & so_environment() const noexcept
Access to the SObjectizer Environment which this agent is belong.
Definition agent.cpp:987
priority_t so_priority() const noexcept
Get the priority of the agent.
Definition agent.hpp:2600
const state_t & so_default_state() const
Access to the agent's default state.
Definition agent.cpp:900
subscription_bind_t so_subscribe(const mbox_t &mbox_ref)
Initiate subscription.
Definition agent.hpp:1404
virtual ~agent_t()
Definition agent.cpp:824
state_time_limit_handling_data_t m_state_time_limit_handling_data
Data that is necessary for handling time limits of agent's states.
Definition agent.hpp:3077
void so_bind_to_dispatcher(event_queue_t &queue) noexcept
Binding agent to the dispatcher.
Definition agent.cpp:1006
void so_destroy_event_subscription(const mbox_t &mbox, const std::type_index &subscription_type, const state_t &target_state)
Destroy event subscription.
Definition agent.hpp:1506
void so_set_delivery_filter_for_mutable_msg(const mbox_t &mbox, Lambda &&lambda)
Set a delivery filter for a mutable message.
Definition agent.hpp:3600
environment_t & m_env
SObjectizer Environment for which the agent is belong.
Definition agent.hpp:2897
void so_deregister_agent_coop(int dereg_reason)
A helper method for deregistering agent's coop.
Definition agent.cpp:1109
void do_drop_subscription(const mbox_t &mbox, const std::type_index &msg_type, const state_t &target_state)
Remove subscription for the state specified.
Definition agent.cpp:1307
agent_t(environment_t &env, agent_tuning_options_t tuning_options)
Constructor which allows specification of agent's tuning options.
Definition agent.cpp:781
handler_finder_t m_handler_finder
Function for searching event handler.
Definition agent.hpp:2874
void define_state_time_limit_handling_data_if_needed()
Initialize data for handling time limit of agent's states.
Definition agent.cpp:1913
virtual void so_evt_start()
Hook on agent start inside SObjectizer.
Definition agent.cpp:832
static demand_handler_pfn_t get_demand_handler_on_enveloped_msg_ptr() noexcept
Definition agent.cpp:1544
void so_create_event_subscription(const mbox_t &mbox_ref, std::type_index type_index, const state_t &target_state, const event_handler_method_t &method, thread_safety_t thread_safety, event_handler_kind_t handler_kind)
Create a subscription for an event.
Definition agent.cpp:1221
void so_set_delivery_filter(const mbox_t &mbox, delivery_filter_unique_ptr_t filter)
Set a delivery filter.
Definition agent.hpp:2471
static void demand_handler_on_enveloped_msg(current_thread_id_t working_thread_id, execution_demand_t &d)
Handles the enveloped message.
Definition agent.cpp:1532
A collector for agent tuning options.
name_for_agent_t m_agent_name
Optional name for an agent.
so_5::priority_t query_priority() const noexcept
Get priority value.
bool m_is_user_provided_subscription_storage_factory
Does a user provide a specific subscription_storage_factory?
agent_tuning_options_t & agent_name(name_for_agent_t name)
Set a name for agent.
subscription_storage_factory_t m_subscription_storage_factory
name_for_agent_t giveout_agent_name() noexcept
Gives away the name for an agent.
friend void swap(so_5::agent_tuning_options_t &a, so_5::agent_tuning_options_t &b) noexcept
message_limit::description_container_t m_message_limits
demands_handling_on_dereg_t m_demands_handling_on_dereg
What to do with pending demands on deregistration.
bool has_agent_name() const noexcept
Does a name specified for an agent?
agent_tuning_options_t & custom_direct_mbox_factory(custom_direct_mbox_factory_t factory)
Set custom direct mbox factory.
const custom_direct_mbox_factory_t & query_custom_direct_mbox_factory() const noexcept
Get a reference to custom direct mbox factory.
so_5::priority_t m_priority
Priority for agent.
bool is_user_provided_subscription_storage_factory() const noexcept
Does a user provide a specific subscription_storage_factory?
static subscription_storage_factory_t default_subscription_storage_factory()
Default subscription storage factory.
const subscription_storage_factory_t & query_subscription_storage_factory() const noexcept
agent_tuning_options_t & message_limits(Args &&... args)
demands_handling_on_dereg_t demands_handling_on_dereg() const noexcept
agent_tuning_options_t & subscription_storage_factory(subscription_storage_factory_t factory) noexcept(noexcept(std::declval< subscription_storage_factory_t & >()=std::move(factory)))
Set factory for subscription storage creation.
message_limit::description_container_t giveout_message_limits()
agent_tuning_options_t & demands_handling_on_dereg(demands_handling_on_dereg_t handling_mode)
Set mode of handling pending demands on deregistration.
agent_tuning_options_t & priority(so_5::priority_t v)
Set priority for agent.
custom_direct_mbox_factory_t m_custom_direct_mbox_factory
Optional factory for custom direct mboxes.
The base class for the object with a reference counting.
atomic_refcounted_t(const atomic_refcounted_t &)=delete
unsigned long dec_ref_count() noexcept
Decrement reference count.
atomic_refcounted_t() noexcept
Default constructor.
atomic_counter_t m_ref_counter
Object reference count.
void inc_ref_count() noexcept
Increments reference count.
~atomic_refcounted_t() noexcept=default
Destructor.
atomic_refcounted_t & operator=(const atomic_refcounted_t &)=delete
It's a kind of strong typedef for coop's deregistration reason.
Definition coop.hpp:80
Type of smart handle for a cooperation.
friend bool operator>=(const coop_handle_t &a, const coop_handle_t &b) noexcept
static constexpr const coop_id_t invalid_coop_id
friend bool operator<(const coop_handle_t &a, const coop_handle_t &b) noexcept
bool operator!() const noexcept
Is this non-empty handle?
friend bool operator==(const coop_handle_t &a, const coop_handle_t &b) noexcept
friend bool operator!=(const coop_handle_t &a, const coop_handle_t &b) noexcept
operator bool() const noexcept
Is this handle empty?
coop_handle_t(coop_id_t id, std::shared_ptr< coop_t > coop)
Initializing constructor.
friend bool operator<=(const coop_handle_t &a, const coop_handle_t &b) noexcept
coop_id_t m_id
ID of cooperation.
auto id() const noexcept
Get the ID of the coop.
friend std::ostream & operator<<(std::ostream &to, const coop_handle_t &what)
A tool for dumping coop_handle to ostream.
std::weak_ptr< coop_t > m_coop
Pointer for cooperation.
friend bool operator>(const coop_handle_t &a, const coop_handle_t &b) noexcept
Agent cooperation.
Definition coop.hpp:389
exception_reaction_t exception_reaction() const noexcept
Get the current exception rection flag for that cooperation.
Definition coop.hpp:758
coop_handle_t handle() noexcept
Get handle for this coop.
Definition coop.hpp:432
A special type that plays role of unique_ptr for coop.
Definition coop.hpp:1342
Interface for creator of new mbox in OOP style.
An interface of delivery filter object.
Definition mbox.hpp:62
delivery_filter_t(delivery_filter_t &&)=delete
virtual bool check(const abstract_message_sink_t &receiver, message_t &msg) const noexcept=0
Checker for a message instance.
delivery_filter_t & operator=(delivery_filter_t &&)=delete
delivery_filter_t(const delivery_filter_t &)=delete
virtual ~delivery_filter_t() noexcept=default
delivery_filter_t & operator=(const delivery_filter_t &)=delete
Helper class for building and registering new cooperation.
decltype(auto) build_and_register_coop(disp_binder_shptr_t binder, Lambda &&lambda)
introduce_coop_helper_t(environment_t &env)
Constructor for the case of creation a cooperation without parent.
coop_handle_t m_parent
Optional parent coop.
introduce_coop_helper_t(environment_t &env, coop_handle_t parent)
Constructor for the case of creation a cooperation with parent.
decltype(auto) introduce(disp_binder_shptr_t binder, L &&lambda)
environment_t & m_env
Environment for creation of cooperation.
decltype(auto) introduce(L &&lambda)
basic_message_holder_impl_t(intrusive_ptr_t< Envelope > msg) noexcept
operator bool() const noexcept
Check for the non-emptiness of message_holder.
bool operator!() const noexcept
Check for the emptiness of message_holder.
bool empty() const noexcept
Check for the emptiness of message_holder.
void reset() noexcept
Drops to pointer to the message instance.
An of mixin with getters for message_holder.
Return_Type & operator*() const noexcept
Get a reference to the message inside message_holder.
Return_Type * get() const noexcept
Get a pointer to the message inside message_holder.
Return_Type * operator->() const noexcept
Get a pointer to the message inside message_holder.
A part of implementation of message_holder to be used for shared ownership of message instances.
intrusive_ptr_t< Envelope > make_reference() const noexcept
Make an another reference to the message.
A part of implementation of message_holder to be used for unique ownership of message instances.
unique_message_holder_impl_t(const unique_message_holder_impl_t &)=delete
unique_message_holder_impl_t & operator=(const unique_message_holder_impl_t &)=delete
intrusive_ptr_t< Envelope > make_reference() noexcept
Extracts the smart pointer to the message.
unique_message_holder_impl_t & operator=(unique_message_holder_impl_t &&) noexcept=default
unique_message_holder_impl_t(unique_message_holder_impl_t &&)=default
message_holder_t< M, Ownership > make_holder() noexcept
Create a holder for this message.
Definition mhood.hpp:197
intrusive_ptr_t< envelope_type > make_reference() noexcept
Create a smart pointer for the message envelope.
Definition mhood.hpp:181
message_holder_t< M, Ownership > make_holder() const noexcept
Create a holder for this message.
Definition mhood.hpp:101
intrusive_ptr_t< envelope_type > make_reference() const noexcept
Create a smart pointer for the message envelope.
Definition mhood.hpp:87
const payload_type * operator->() const noexcept
Access to the message via pointer.
Definition mhood.hpp:112
intrusive_ptr_t< envelope_type > make_reference() noexcept
Create a smart pointer for the message envelope.
Definition mhood.hpp:380
message_holder_t< M, Ownership > make_holder() noexcept
Create a holder for this message.
Definition mhood.hpp:399
message_holder_t< M, Ownership > make_holder() const noexcept
Create a holder for this message.
Definition mhood.hpp:299
const payload_type * operator->() const noexcept
Access to the message via pointer.
Definition mhood.hpp:310
intrusive_ptr_t< envelope_type > make_reference() const noexcept
Create a smart pointer for the message envelope.
Definition mhood.hpp:285
A type to be used as a base for mhood_t implementation.
Definition mhood.hpp:52
Helper template class for do rollback actions automatically in the destructor.
Helper class for scope exit implementation.
Alias for namespace with traits of event queue.
Alias for namespace with traits of event queue.
Interface for dispatcher binders.
disp_binder_t(const disp_binder_t &)=delete
virtual void bind(agent_t &agent) noexcept=0
Bind agent to dispatcher.
virtual void unbind(agent_t &agent) noexcept=0
Unbind agent from dispatcher.
disp_binder_t & operator=(const disp_binder_t &)=delete
disp_binder_t(disp_binder_t &&)=delete
virtual void preallocate_resources(agent_t &agent)=0
Allocate resources in dispatcher for new agent.
disp_binder_t()=default
disp_binder_t & operator=(disp_binder_t &&)=delete
virtual void undo_preallocation(agent_t &agent) noexcept=0
Undo resources allocation.
virtual ~disp_binder_t() noexcept=default
An interface of envelope with some message/signal inside.
virtual ~envelope_t() override=default
envelope_t(const envelope_t &)=default
envelope_t & operator=(envelope_t &&) noexcept=default
envelope_t & operator=(const envelope_t &)=default
kind_t so5_message_kind() const noexcept override
Detect the kind of the message.
virtual void access_hook(access_context_t context, handler_invoker_t &invoker) noexcept=0
envelope_t(envelope_t &&)=default
An extended version of handling_context which can be used for calling event handler.
handler_invoker_t(const handler_invoker_t &)=default
handler_invoker_t(handler_invoker_t &&)=default
handler_invoker_t & operator=(const handler_invoker_t &)=default
handler_invoker_t & operator=(handler_invoker_t &&) noexcept=default
virtual void invoke(const payload_info_t &payload) noexcept=0
Call an actual handler for the enveloped message/signal.
An implementation of handler_invoker interface.
An information about payload inside envelope.
message_ref_t m_message
Actual enveloped message.
message_ref_t & message() const noexcept
payload_info_t(message_ref_t message)
Initializing constructor.
Parameters for the SObjectizer Environment initialization.
event_queue_hook_unique_ptr_t m_event_queue_hook
An event_queue_hook object.
layer_map_t m_so_layers
Additional layers.
so_5::disp::abstract_work_thread_factory_shptr_t so5_giveout_work_thread_factory()
Take out work_thread_factory object.
environment_infrastructure_factory_t m_infrastructure_factory
A factory for environment infrastructure entity.
environment_params_t & event_exception_logger(event_exception_logger_unique_ptr_t logger)
Set exception logger object.
bool m_autoshutdown_disabled
Is autoshutdown when there is no more cooperation disabled?
queue_locks_defaults_manager_unique_ptr_t so5_giveout_queue_locks_defaults_manager()
Take out queue locks defaults manager.
environment_params_t & default_subscription_storage_factory(subscription_storage_factory_t factory)
Set subscription storage factory to be used by default.
environment_params_t & infrastructure_factory(environment_infrastructure_factory_t factory)
Set new environment infrastructure factory.
environment_params_t & work_thread_factory(so_5::disp::abstract_work_thread_factory_shptr_t factory)
Set work thread factory to be used by default.
environment_params_t & default_disp_params(so_5::disp::nef_one_thread::disp_params_t params)
Set parameters for a case when nef_one_thread-disp must be used as the default dispatcher.
default_disp_params_t m_default_disp_params
Parameters for the default dispatcher.
void add_layer(const std::type_index &type, layer_unique_ptr_t layer_ptr)
Add an additional layer.
bool autoshutdown_disabled() const
Is autoshutdown disabled?
coop_listener_unique_ptr_t so5_giveout_coop_listener()
Get cooperation listener.
environment_params_t & turn_work_thread_activity_tracking_off()
Helper for turning work thread activity tracking off.
environment_params_t & disable_autoshutdown()
Do not shutdown SO Environment when it is becomes empty.
so_5::msg_tracing::tracer_unique_ptr_t so5_giveout_message_delivery_tracer()
Get message delivery tracer for the environment.
environment_params_t & message_delivery_tracer(so_5::msg_tracing::tracer_unique_ptr_t tracer)
Set message delivery tracer for the environment.
environment_params_t & queue_locks_defaults_manager(queue_locks_defaults_manager_unique_ptr_t manager)
Set manager for queue locks defaults.
environment_params_t & error_logger(error_logger_shptr_t logger)
Set error logger for the environment.
environment_params_t & default_disp_params(so_5::disp::one_thread::disp_params_t params)
Set parameters for a case when one_thread-disp must be used as the default dispatcher.
environment_params_t & work_thread_activity_tracking(work_thread_activity_tracking_t flag)
Set activity tracking flag for the whole SObjectizer Environment.
void event_queue_hook(event_queue_hook_unique_ptr_t hook)
Set event_queue_hook object.
environment_params_t & add_layer(std::unique_ptr< SO_Layer > layer_ptr)
Add an additional layer to the SObjectizer Environment.
so_5::msg_tracing::filter_shptr_t so5_giveout_message_delivery_tracer_filter()
Get message delivery tracer filter for the environment.
queue_locks_defaults_manager_unique_ptr_t m_queue_locks_defaults_manager
Manager for defaults of queue locks.
environment_params_t(environment_params_t &&other)
Move constructor.
so_5::timer_thread_factory_t so5_giveout_timer_thread_factory()
Get the timer_thread factory.
const environment_infrastructure_factory_t & infrastructure_factory() const
Get the current environment infrastructure factory.
friend SO_5_FUNC void swap(environment_params_t &a, environment_params_t &b) noexcept
Swap operation.
environment_params_t & coop_listener(coop_listener_unique_ptr_t coop_listener)
Set cooperation listener object.
environment_params_t & turn_work_thread_activity_tracking_on()
Helper for turning work thread activity tracking on.
layer_map_t so5_giveout_layers_map()
Get map of default SObjectizer's layers.
so_5::msg_tracing::tracer_unique_ptr_t m_message_delivery_tracer
Tracer for message delivery.
exception_reaction_t exception_reaction() const noexcept
Get exception reaction flag value.
error_logger_shptr_t m_error_logger
Error logger for the environment.
environment_params_t & message_delivery_tracer_filter(so_5::msg_tracing::filter_shptr_t filter)
Set message tracer filter for the environment.
environment_params_t & exception_reaction(exception_reaction_t value) noexcept
Set exception reaction flag value.
subscription_storage_factory_t m_default_subscription_storage_factory
Default subscription storage factory.
const default_disp_params_t & default_disp_params() const
Get the parameters for the default dispatcher.
so_5::disp::abstract_work_thread_factory_shptr_t m_work_thread_factory
Global factory for work threads.
environment_params_t()
Constructor.
event_exception_logger_unique_ptr_t m_event_exception_logger
Exception logger.
event_queue_hook_unique_ptr_t so5_giveout_event_queue_hook()
Take out event_queue_hook object.
so_5::msg_tracing::filter_shptr_t m_message_delivery_tracer_filter
Message delivery tracer filter to be used with environment.
work_thread_activity_tracking_t work_thread_activity_tracking() const
Get activity tracking flag for the whole SObjectizer Environment.
const error_logger_shptr_t & so5_error_logger() const
Get error logger for the environment.
environment_params_t & operator=(environment_params_t &&other) noexcept
Move operator.
event_exception_logger_unique_ptr_t so5_giveout_event_exception_logger()
Get exception logger.
coop_listener_unique_ptr_t m_coop_listener
Cooperation listener.
environment_params_t & timer_thread(so_5::timer_thread_factory_t factory)
Set the timer_thread factory.
exception_reaction_t m_exception_reaction
Exception reaction flag for the whole SO Environment.
work_thread_activity_tracking_t m_work_thread_activity_tracking
Work thread activity tracking for the whole Environment.
const subscription_storage_factory_t & default_subscription_storage_factory() const noexcept
Get the current default subscription storage factory.
so_5::timer_thread_factory_t m_timer_thread_factory
Timer thread factory.
SObjectizer Environment.
disp_binder_shptr_t so_make_default_disp_binder()
Get binding to the default dispatcher.
mbox_t create_mbox()
Create an anonymous MPMC mbox.
error_logger_t & error_logger() const
Get the error_logger object.
void imp_run_layers_and_go_further()
Run layers and call next run stage.
void add_extra_layer(const std::type_index &type, const layer_ref_t &layer)
Add an additional layer.
so_5::timer_id_t so_schedule_timer(const low_level_api::schedule_timer_params_t params)
Schedule timer event.
stats::repository_t & stats_repository()
Access to repository of data sources for run-time monitoring.
void add_extra_layer(std::unique_ptr< SO_Layer > layer_ptr)
Add an additional layer.
void change_message_delivery_tracer_filter(so_5::msg_tracing::filter_shptr_t filter)
Change the current msg_tracing's filter to a new one.
coop_handle_t register_agent_as_coop(std::unique_ptr< A > agent)
Register single agent as a cooperation.
void install_exception_logger(event_exception_logger_unique_ptr_t logger)
Set up an exception logger.
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.
SO_Layer * query_layer_noexcept() const
void run()
Run the SObjectizer Run-Time.
environment_t & operator=(const environment_t &)=delete
void remove_extra_layer(const std::type_index &type)
Remove an additional layer.
mchain_t create_mchain(const mchain_params_t &params)
Create message chain.
exception_reaction_t exception_reaction() const noexcept
An exception reaction for the whole SO Environment.
std::unique_ptr< internals_t > m_impl
SObjectizer Environment internals.
environment_t & self_ref()
Auxiliary methods for getting reference to itself.
std::unique_ptr< Agent > make_agent(Args &&... args)
Helper method for simplification of agents creation.
coop_handle_t register_agent_as_coop(std::unique_ptr< A > agent, disp_binder_shptr_t disp_binder)
Register single agent as a cooperation with specified dispatcher binder.
coop_unique_holder_t make_coop(coop_handle_t parent)
Create a new cooperation that will be a child for specified parent coop.
so_5::disp::abstract_work_thread_factory_shptr_t work_thread_factory() const noexcept
Access to the global work thread factory.
void call_exception_logger(const std::exception &event_exception, const coop_handle_t &coop) noexcept
Call event exception logger for logging an exception.
environment_t(environment_params_t &&so_environment_params)
stats::controller_t & stats_controller()
Access to controller of run-time monitoring.
layer_t * query_layer(const std::type_index &type) const
Access to an additional layer.
mbox_t make_custom_mbox(Lambda &&lambda)
Create a custom mbox.
void imp_run_infrastructure()
Launch environment infrastructure and wait for finish.
void imp_run_stats_controller_and_go_further()
Run controller for run-time monitoring and call next run stage.
coop_unique_holder_t make_coop()
Create a cooperation.
void stop() noexcept
Send a shutdown signal to the Run-Time.
work_thread_activity_tracking_t work_thread_activity_tracking() const
Get activity tracking flag for the whole SObjectizer Environment.
decltype(auto) introduce_coop(Args &&... args)
Helper method for simplification of cooperation creation and registration.
mbox_t do_make_custom_mbox(custom_mbox_details::creator_iface_t &creator)
Actual creation of a custom mbox.
void remove_stop_guard(stop_guard_shptr_t guard)
Remove stop_guard and complete the stop operation if necessary.
environment_t(const environment_t &)=delete
coop_handle_t register_coop(coop_unique_holder_t agent_coop)
Register a cooperation.
void deregister_coop(coop_handle_t coop, int reason) noexcept
Deregister the cooperation.
SO_Layer * query_layer() const
Get access to the layer with exception if layer is not found.
coop_unique_holder_t make_coop(disp_binder_shptr_t disp_binder)
Create a cooperation with specified dispatcher binder.
virtual void init()=0
Initialization hook.
mbox_t create_mbox(nonempty_name_t mbox_name)
Create named MPMC mbox.
void so_single_timer(const low_level_api::single_timer_params_t params)
Schedule a single shot timer event.
stop_guard_t::setup_result_t setup_stop_guard(stop_guard_shptr_t guard, stop_guard_t::what_if_stop_in_progress_t reaction_on_stop_in_progress=stop_guard_t::what_if_stop_in_progress_t::throw_exception)
Set up a new stop_guard.
bool autoshutdown_disabled() const
Get autoshutdown_disabled flag.
coop_unique_holder_t make_coop(coop_handle_t parent, disp_binder_shptr_t disp_binder)
Create a new cooperation that will be a child for specified parent coop.
An interface for logging error messages.
error_logger_t & operator=(error_logger_t &)=delete
virtual ~error_logger_t() noexcept=default
error_logger_t(const error_logger_t &)=delete
error_logger_t()=default
virtual void log(const char *file_name, unsigned int line, const std::string &message)=0
A method for logging message.
Interface of event_queue_hook object.
An interface of event queue for agent.
event_queue_t & operator=(const event_queue_t &)=delete
event_queue_t & operator=(event_queue_t &&)=delete
virtual void push(execution_demand_t demand)=0
Enqueue new event to the queue.
virtual ~event_queue_t() noexcept=default
virtual void push_evt_finish(execution_demand_t demand) noexcept=0
Enqueue a demand for evt_finish event.
virtual void push_evt_start(execution_demand_t demand)=0
Enqueue a demand for evt_start event.
event_queue_t(event_queue_t &&)=delete
event_queue_t()=default
event_queue_t(const event_queue_t &)=delete
The base class for all SObjectizer exceptions.
Definition exception.hpp:34
int error_code() const noexcept
Error code getter.
Definition exception.hpp:53
exception_t(const exception_t &)=default
exception_t(exception_t &&)=default
int m_error_code
Error code.
Definition exception.hpp:64
exception_t(const std::string &error_descr, int error_code)
Definition exception.hpp:36
exception_t & operator=(exception_t &&o) noexcept=default
exception_t & operator=(exception_t &o)=default
static void raise(const char *file_name, unsigned int line_number, std::string_view error_descr, int error_code)
Definition exception.cpp:17
A hint for a dispatcher for execution of event for the concrete execution_demand.
bool is_thread_safe() const
Is thread safe handler?
execution_hint_t(execution_demand_t &demand)
execution_hint_t(execution_demand_t &demand, direct_func_t direct_func, thread_safety_t thread_safety)
Initializing constructor.
thread_safety_t m_thread_safety
Thread safety for event handler.
void exec(current_thread_id_t working_thread_id) const
Call event handler directly.
direct_func_t m_direct_func
Function for call event handler directly.
static execution_hint_t create_empty_execution_hint(execution_demand_t &demand)
execution_demand_t & m_demand
A reference to demand for which that hint has been created.
A special class for accessing private members of agent_coop.
static void decrement_usage_count(coop_t &coop)
static void increment_usage_count(coop_t &coop) noexcept
Storage for message delivery filters.
A helper class for accessing the functionality of environment-class which is specific for SObjectizer...
event_queue_t * event_queue_on_bind(agent_t *agent, event_queue_t *original_queue) noexcept
Call the event_queue_hook when an agent is being bound to a particular event_queue.
void event_queue_on_unbind(agent_t *agent, event_queue_t *queue) noexcept
Call the event_queue_hook when an agent is being unbound from its event_queue.
bool is_msg_tracing_enabled() const
Is message delivery tracing enabled?
internal_env_iface_t(environment_t &env)
Initializing constructor.
mbox_t create_limitless_mpsc_mbox(agent_t &single_consumer)
Create multi-producer/single-consumer mbox that ignores message limits.
An utility class for working with layers.
Helper class for accessing protected members from mbox interface.
An interface for storage of message_sinks for one agent.
void add(internal_state_listener_unique_ptr_t listener)
Add a new listener.
static auto wrap_nondestroyable(agent_state_listener_t &listener)
static void actual_deleter(agent_state_listener_t *listener)
static void noop_deleter(agent_state_listener_t *)
void changed(agent_t &agent, const state_t &state) noexcept
Handle state change.
static auto wrap_destroyable(agent_state_listener_unique_ptr_t listener)
agent_t::agent_status_t m_previous_status
Definition agent.cpp:910
state_switch_guard_t(agent_t &agent)
Definition agent.cpp:913
An interface of subscription storage.
Template class for smart reference wrapper on the atomic_refcounted_t.
bool operator==(const intrusive_ptr_t &o) const
intrusive_ptr_t(T *obj) noexcept
Constructor for a raw pointer.
T * m_obj
Object controlled by a smart reference.
void dismiss_object() noexcept
Decrement reference count to object and delete it if needed.
void reset() noexcept
Drop controlled object.
intrusive_ptr_t(const intrusive_ptr_t< Y > &o) noexcept
Constructor from another smart reference.
intrusive_ptr_t(std::unique_ptr< Y > o) noexcept
Constructor from unique_ptr instance.
intrusive_ptr_t(intrusive_ptr_t &&o) noexcept
Move constructor.
bool operator<(const intrusive_ptr_t &o) const
T * operator->() const noexcept
intrusive_ptr_t(const intrusive_ptr_t &o) noexcept
Copy constructor.
intrusive_ptr_t & operator=(const intrusive_ptr_t &o) noexcept
Copy operator.
intrusive_ptr_t & operator=(intrusive_ptr_t &&o) noexcept
Move operator.
intrusive_ptr_t< Y > make_reference() const noexcept
Make reference with casing to different type.
T & operator*() const noexcept
void take_object() noexcept
Increment reference count to object if it's not null.
friend void swap(intrusive_ptr_t &a, intrusive_ptr_t &b) noexcept
Swap values.
intrusive_ptr_t() noexcept
Default constructor.
T * get() const noexcept
~intrusive_ptr_t() noexcept
Destructor.
operator bool() const noexcept
Is this a null reference?
An interface of the additional SObjectizer Environment layer.
Definition so_layer.hpp:31
conductor_t(const Env &env, const char *file, unsigned int line)
conductor_t(error_logger_t &logger, const char *file, unsigned int line)
An implementation of delivery filter represented by lambda-function like object.
Definition mbox.hpp:126
bool check(const abstract_message_sink_t &, message_t &msg) const noexcept override
Checker for a message instance.
Definition mbox.hpp:135
A class for the name of mbox_namespace.
Parameters for message chain.
Definition mchain.hpp:741
A class for holding an instance of a message.
static message_holder_t make(Args &&...args)
Create a new instance of message_holder with a new message inside.
friend void swap(message_holder_t &a, message_holder_t &b) noexcept
message_holder_t(std::piecewise_construct_t, Args &&...args)
static intrusive_ptr_t< envelope_type > make_msg_instance(Args &&...args)
Create a new instance of message.
An interface of tracer for message delivery tracing.
A base class for agent messages.
Definition message.hpp:47
message_t(const message_t &other)
Definition message.cpp:19
virtual void so5_change_mutability(message_mutability_t mutability)
Change message mutabilty flag.
Definition message.hpp:228
message_t & operator=(message_t &&other) noexcept
Definition message.cpp:39
friend message_mutability_t message_mutability(const message_t &what) noexcept
Helper method for get message mutability flag.
Definition message.hpp:86
virtual kind_t so5_message_kind() const noexcept
Detect the kind of the message.
Definition message.hpp:248
virtual ~message_t() noexcept=default
friend message_kind_t message_kind(const message_t &what)
Helper method for quering kind of the message.
Definition message.hpp:174
message_t & operator=(const message_t &other)
Definition message.cpp:32
message_mutability_t m_mutability
Is message mutable or immutable?
Definition message.hpp:188
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
virtual message_mutability_t so5_message_mutability() const noexcept
Get message mutability flag.
Definition message.hpp:203
message_t(message_t &&other)
Definition message.cpp:25
friend void change_message_mutability(message_t &what, message_mutability_t mutability)
Helper method for change message mutability flag.
Definition message.hpp:130
friend message_kind_t message_kind(const so_5::intrusive_ptr_t< message_t > &what)
Helper method for quering kind of the message.
Definition message.hpp:154
friend void change_message_mutability(intrusive_ptr_t< message_t > &what, message_mutability_t mutability)
Helper method for safe change message mutability flag.
Definition message.hpp:107
A message wrapped to be used as type of argument for event handlers.
Definition mhood.hpp:570
mhood_t(message_ref_t &mf)
Definition mhood.hpp:574
Type for holding agent name.
unsigned int m_length
Name length.
name_for_agent_t & operator=(name_for_agent_t &&other) noexcept
Definition agent.cpp:142
name_for_agent_t(const name_for_agent_t &)
Definition agent.cpp:115
name_for_agent_t(name_for_agent_t &&other) noexcept
Definition agent.cpp:136
std::unique_ptr< char[] > m_value
Name storage.
bool has_value() const noexcept
Does this object have a value?
Definition agent.cpp:169
name_for_agent_t & operator=(const name_for_agent_t &)
Definition agent.cpp:129
std::string_view as_string_view() const
Get the value as a string_view.
Definition agent.cpp:160
name_for_agent_t()
Default constructor makes an null value.
Definition agent.cpp:104
operator bool() const noexcept
Does this object have a value?
name_for_agent_t(std::string_view value)
Initializing constructor.
Definition agent.cpp:108
A class for the name which cannot be empty.
Helper class for indication of long-lived reference via its type.
Definition outliving.hpp:98
outliving_reference_t(T &r) noexcept
outliving_reference_t & operator=(outliving_reference_t const &o)=delete
T & get() const noexcept
outliving_reference_t(outliving_reference_t< U > const &o) noexcept
outliving_reference_t(T &&)=delete
outliving_reference_t(outliving_reference_t const &o) noexcept
Wrapper around a pointer to partially constructed agent.
An implementation of backoff object using assembly instruction.
Definition spinlocks.hpp:60
Scoped guard for shared locks.
read_lock_guard_t(const read_lock_guard_t &)=delete
read_lock_guard_t & operator=(const read_lock_guard_t &)=delete
A simple multi-readers/single-writer spinlock (analog of std::shared_mutex).
void lock()
Lock object in exclusive mode.
static constexpr const std::uint_fast32_t unlocked
void unlock()
Unlock object locked in exclusive mode.
void unlock_shared()
Unlock object locked in shared mode.
std::atomic_uint_fast32_t m_counters
void lock_shared()
Lock object in shared mode.
static constexpr const std::uint_fast32_t write_lock
static constexpr const std::uint_fast32_t read_lock
rw_spinlock_t & operator=(const rw_spinlock_t &)=delete
rw_spinlock_t(const rw_spinlock_t &)=delete
A base class for agent signals.
Definition message.hpp:275
signal_t(const signal_t &)=delete
signal_t(signal_t &&)=delete
signal_t & operator=(signal_t &&)=delete
kind_t so5_message_kind() const noexcept override
Detect the kind of the message.
Definition message.hpp:293
signal_t & operator=(const signal_t &)=delete
~signal_t() noexcept override=default
signal_t()=default
abstract_message_sink_t & sink() noexcept override
Get a reference to the underlying message sink.
simple_sink_owner_t(Args &&...args)
Initializing constructor.
const abstract_message_sink_t & sink() const noexcept override
Get a const reference to the underlying message sink.
A simple spinlock (analog of std::mutex).
Definition spinlocks.hpp:93
void lock()
Lock object.
void unlock()
Unlock object.
spinlock_t(const spinlock_t &)=delete
std::atomic_bool m_flag
Atomic flag which is used as actual lock.
spinlock_t & operator=(spinlock_t &&)=delete
spinlock_t & operator=(const spinlock_t &)=delete
spinlock_t(spinlock_t &&)=delete
Helper class for simplify iteration on state's path.
Definition state.hpp:1841
state_t::path_t::const_iterator end() const noexcept
Get the past-the-end iterator for the path.
Definition state.hpp:1881
state_path_t & operator=(state_path_t &&)=delete
state_t::path_t m_path
Path for the state.
Definition state.hpp:1843
state_path_t(const state_path_t &)=delete
state_t::path_t::const_iterator m_past_the_end_it
Definition state.hpp:1849
state_path_t & operator=(const state_path_t &)=delete
state_path_t(const state_t &state) noexcept
Initializing constructor.
Definition state.hpp:1853
state_path_t(state_path_t &&)=delete
state_t::path_t::const_iterator begin() const noexcept
Get iterator for the very first item of the path.
Definition state.hpp:1873
Information of time_limit for a state.
Definition agent.cpp:199
void change(duration_t limit, const state_t &state_to_switch) noexcept
Definition agent.cpp:224
const state_t & state_to_switch() const noexcept
Definition agent.cpp:314
void on_state_activation(const agent_t::state_time_limit_handling_data_t &info) noexcept
Definition agent.cpp:243
bool is_limit_exceeded(const steady_clock::time_point current_time) const noexcept
Definition agent.cpp:300
std::optional< activation_data_t > m_activation_data
Definition agent.cpp:355
std::reference_wrapper< const state_t > m_state_to_switch
The target state to switch after the timeout.
Definition agent.cpp:350
void activate(const agent_t::state_time_limit_handling_data_t &info)
Definition agent.cpp:268
time_limit_t(duration_t limit, const state_t &state_to_switch) noexcept
Initializing constructor.
Definition agent.cpp:208
void on_state_deactivation() noexcept
Definition agent.cpp:254
bool is_target(const agent_t *agent) const noexcept
Is agent owner of this state?
Definition agent.cpp:552
state_t & time_limit(duration_t timeout, const state_t &state_to_switch)
Set up a time limit for the state.
Definition agent.cpp:569
std::enable_if< details::is_agent_method_pointer< details::method_arity::nullary, Method_Pointer >::value, state_t & >::type on_enter(Method_Pointer pfn)
Set on enter handler.
Definition agent.hpp:4042
bool has_subscription(const mbox_t &from, Method_Pointer &&pfn) const
Check the presence of a subscription.
Definition agent.hpp:3949
const state_t & just_switch_to(mbox_t from, const state_t &target_state) const
Define handler which only switches agent to the specified state.
Definition agent.hpp:4000
state_t & drop_time_limit()
Drop time limit for the state if defined.
Definition agent.cpp:618
on_exit_handler_t m_on_exit
Handler for the exit from the state.
Definition state.hpp:1687
const state_t & suppress(mbox_t from) const
Suppress processing of event in this state.
Definition agent.hpp:4027
state_t & transfer_to_state(mbox_t from, const state_t &target_state)
An instruction for switching agent to the specified state and transfering event proceessing to new st...
Definition state.hpp:764
history_t m_state_history
Type of state history.
Definition state.hpp:1643
const state_t * parent_state() const noexcept
Get a parent state if exists.
Definition state.hpp:1719
void fill_path(path_t &path) const noexcept
A helper method for building a path from top-level state to this state.
Definition state.hpp:1761
state_t(substate_of parent, history_t state_history)
Constructor for the case when state is a substate of some parent state.
state_t & on_exit(on_exit_handler_t handler)
Set on exit handler.
Definition state.hpp:1301
state_t(initial_substate_of parent, std::string state_name, history_t state_history)
Constructor for the case when state is the initial substate of some parent state.
Definition agent.cpp:427
state_t(substate_of parent)
Constructor for the case when state is a substate of some parent state.
Definition agent.cpp:447
state_t & just_switch_to(mbox_t from, const state_t &target_state)
Define handler which only switches agent to the specified state.
Definition state.hpp:902
std::size_t nested_level() const noexcept
Query nested level for the state.
Definition state.hpp:1749
bool is_active() const noexcept
Is this state or any of its substates activated?
Definition agent.hpp:3918
state_t(state_t &&other)
Move constructor.
Definition agent.cpp:470
state_t(agent_t *target_agent, std::string state_name, state_t *parent_state, std::size_t nested_level, history_t state_history)
Fully initializing constructor.
Definition agent.cpp:362
const state_t & subscribe_message_handler(const mbox_t &from, Args &&... args) const
A helper for handle-methods implementation.
Definition agent.hpp:4082
const state_t & event(Args &&... args) const
Helper for subscription of event handler in this state.
Definition agent.hpp:3925
const state_t & suppress() const
Suppress processing of event in this state.
Definition agent.hpp:4020
std::string m_state_name
State name.
Definition state.hpp:1611
state_t(agent_t *agent, std::string state_name, history_t state_history)
Definition agent.cpp:409
bool has_subscription(const mbox_t &from) const
Check the presence of a subscription.
Definition agent.hpp:3942
state_t * m_parent_state
Parent state.
Definition state.hpp:1624
state_t(substate_of parent, std::string state_name, history_t state_history)
Constructor for the case when state is a substate of some parent state.
Definition agent.cpp:458
const state_t * actual_state_to_enter() const
Find actual state to be activated for agent.
Definition agent.cpp:626
void drop_subscription(const mbox_t &from, Method_Pointer &&pfn) const
Drop subscription.
Definition agent.hpp:3968
state_t & on_enter(on_enter_handler_t handler)
Set on enter handler.
Definition state.hpp:1174
state_t(initial_substate_of parent)
Constructor for the case when state is the initial substate of some parent state.
Definition agent.cpp:416
state_t & transfer_to_state(const state_t &target_state)
An instruction for switching agent to the specified state and transfering event proceessing to new st...
Definition state.hpp:804
const state_t * m_initial_substate
The initial substate.
Definition state.hpp:1636
bool operator==(const state_t &state) const noexcept
Definition agent.cpp:492
void clear_history() noexcept
Clear state history.
Definition state.hpp:434
state_t(initial_substate_of parent, std::string state_name)
Constructor for the case when state is the initial substate of some parent state.
Definition agent.cpp:421
state_t & event(mbox_t from, Args &&... args)
Definition state.hpp:512
const state_t & just_switch_to(const state_t &target_state) const
Define handler which only switches agent to the specified state.
Definition agent.hpp:4011
size_t m_substate_count
Number of substates.
Definition state.hpp:1673
state_t(agent_t *agent, history_t state_history)
Definition agent.cpp:396
const on_exit_handler_t & on_exit() const
Query on enter handler.
Definition state.hpp:1391
void call_on_enter() const noexcept
Call for on enter handler if defined.
Definition state.hpp:1801
bool operator!=(const state_t &state) const noexcept
Definition state.hpp:360
void call_on_exit() const noexcept
Call for on exit handler if defined.
Definition state.hpp:1813
agent_t *const m_target_agent
Owner of this state.
Definition state.hpp:1605
const state_t & transfer_to_state(mbox_t from, const state_t &target_state) const
An instruction for switching agent to the specified state and transfering event proceessing to new st...
Definition agent.hpp:3980
std::string query_name() const
Get textual name of the state.
Definition agent.cpp:498
state_t & operator=(const state_t &)=delete
const state_t & transfer_to_state(const state_t &target_state) const
An instruction for switching agent to the specified state and transfering event proceessing to new st...
Definition agent.hpp:3991
static constexpr const std::size_t max_deep
Max deep of nested states.
Definition state.hpp:165
state_t(substate_of parent, std::string state_name)
Constructor for the case when state is a substate of some parent state.
Definition agent.cpp:452
const state_t * m_last_active_substate
Last active substate.
Definition state.hpp:1654
void handle_time_limit_on_enter() const
A special handler of time limit to be used on entering into state.
Definition agent.cpp:670
state_t(agent_t *agent, std::string state_name)
Definition agent.cpp:403
state_t & suppress(mbox_t from)
Suppress processing of event in this state.
Definition state.hpp:1132
state_t(const state_t &)=delete
const state_t & event(mbox_t from, Args &&... args) const
Helper for subscription of event handler in this state.
Definition agent.hpp:3934
void activate() const
Switch agent to that state.
Definition agent.cpp:563
void drop_subscription(const mbox_t &from) const
Drop subscription.
Definition agent.hpp:3961
history_t
Type of history for state.
Definition state.hpp:173
@ none
State has no history.
@ deep
State has deep history.
@ shallow
State has shallow history.
on_enter_handler_t m_on_enter
Handler for the enter to the state.
Definition state.hpp:1680
const on_enter_handler_t & on_enter() const
Query on enter handler.
Definition state.hpp:1267
state_t & event(Args &&... args)
Definition state.hpp:471
std::unique_ptr< time_limit_t > m_time_limit
A definition of time limit for the state.
Definition state.hpp:1696
state_t & suppress()
Suppress processing of event in this state.
Definition state.hpp:1081
std::size_t m_nested_level
Nesting level for state.
Definition state.hpp:1663
void update_history_in_parent_states() const
A helper method which is used during state change for update state with history.
Definition agent.cpp:649
void handle_time_limit_on_exit() const
A special handler of time limit to be used on exiting from state.
Definition agent.cpp:677
state_t & just_switch_to(const state_t &target_state)
Define handler which only switches agent to the specified state.
Definition state.hpp:938
state_t(initial_substate_of parent, history_t state_history)
Constructor for the case when state is the initial substate of some parent state.
state_t(agent_t *agent)
Definition agent.cpp:390
A public interface for control SObjectizer monitoring options.
An interface of data sources repository.
An interface of stop_guard entity.
setup_result_t
Type for result of setting up a new stop_guard.
@ throw_exception
An exception must be thrown.
A class for creating a subscription to messages from the mbox.
Definition agent.hpp:174
std::vector< const state_t * > state_vector_t
Type of vector of states.
Definition agent.hpp:414
mbox_t m_mbox_ref
Mbox for messages to subscribe.
Definition agent.hpp:407
subscription_bind_t & just_switch_to(const state_t &target_state)
Define handler which only switches agent to the specified state.
Definition agent.hpp:3856
void create_subscription_for_states(const std::type_index &msg_type, const event_handler_method_t &method, thread_safety_t thread_safety, event_handler_kind_t handler_kind) const
Create subscription of event for all states.
Definition agent.hpp:3879
subscription_bind_t(agent_t &agent, const mbox_t &mbox_ref)
Definition agent.hpp:3627
subscription_bind_t & in(const state_t &state)
Set up a state in which events are allowed be processed.
Definition agent.hpp:3636
subscription_bind_t & suppress()
Suppress processing of event in this state.
Definition agent.hpp:3832
subscription_bind_t & transfer_to_state(const state_t &target_state)
An instruction for switching agent to the specified state and transfering event proceessing to new st...
Definition agent.hpp:3699
state_vector_t m_states
States of agents the event to be subscribed in.
Definition agent.hpp:421
void ensure_handler_can_be_used_with_mbox(const so_5::details::msg_type_and_handler_pair_t &handler) const
Additional check for subscription to a mutable message from MPMC mbox.
Definition agent.hpp:3906
agent_t * m_agent
Agent to which we are subscribing.
Definition agent.hpp:405
An indentificator for the timer.
Definition timers.hpp:82
A result of message transformation.
transformed_message_t(mbox_t mbox, std::unique_ptr< typename message_payload_type< Msg >::envelope_type > msg)
Initializing constructor for the case when Msg is a message type.
message_ref_t m_message
Instance of transformed message.
const mbox_t & mbox() const
Destination message box.
mbox_t m_mbox
Destination message box.
std::type_index msg_type() const
Type of the transformed message.
transformed_message_t(mbox_t mbox)
Initializing constructor for the case when Msg is a signal type.
const message_ref_t & message() const
Instance of transformed message.
static transformed_message_t< Msg > make(mbox_t mbox, Args &&... args)
A helper method for transformed_message construction.
transformed_message_t(mbox_t mbox, message_holder_t< Msg_In_Holder, Ownership > msg_holder)
An implementation of backoff object with usage of std::yield.
Definition spinlocks.hpp:38
#define SO_5_EXPORT
Definition declspec.hpp:26
#define SO_5_TYPE
Definition declspec.hpp:46
#define SO_5_IMPORT
Definition declspec.hpp:27
#define SO_5_FUNC
Definition declspec.hpp:48
#define SO_5_LOG_ERROR(logger, var_name)
A special macro for helping error logging.
#define SO_5_LOG_ERROR_IMPL(logger, file, line, var_name)
An implementation for SO_5_LOG_ERROR macro.
#define SO_5_THROW_EXCEPTION_IMPL(file, line, error_code, desc)
Definition exception.hpp:71
#define SO_5_THROW_EXCEPTION(error_code, desc)
Definition exception.hpp:74
demand_handler_pfn_t select_demand_handler_for_message(const agent_t &agent, const message_ref_t &msg)
A helper function to select actual demand handler in dependency of message kind.
Definition agent.cpp:1365
mbox_t make_direct_mbox_with_respect_to_custom_factory(partially_constructed_agent_ptr_t agent_ptr, const agent_tuning_options_t &tuning_options, mbox_t standard_mbox)
Helper for creation of the direct mbox for an agent.
Definition agent.cpp:722
unsigned int ensure_valid_agent_name_length(std::size_t length)
Definition agent.cpp:83
std::string create_anonymous_state_name(const agent_t *agent, const state_t *st)
Definition agent.cpp:183
const state_t deadletter_state(nullptr, "<DEADLETTER_STATE>")
A special object to be used as state for make subscriptions for deadletter handlers.
subscription_storage_factory_t detect_subscription_storage_factory_to_use(environment_t &env, const agent_tuning_options_t &tuning_options)
Helper for selection of subscription storage factory.
Definition agent.cpp:759
const state_t awaiting_deregistration_state(nullptr, "<AWAITING_DEREGISTRATION_AFTER_UNHANDLED_EXCEPTION>")
A special object for the state in which agent is awaiting for deregistration after unhandled exceptio...
Enumeration of cooperation deregistration reasons.
Definition coop.hpp:39
const int normal
Normal deregistration.
Definition coop.hpp:46
Various helpers for event subscription.
Agent * get_actual_agent_pointer(agent_t &agent)
Get actual agent pointer.
details::msg_type_and_handler_pair_t make_handler_from_lambda_of_free_function(Lambda &&lambda)
A function for creation event handler.
msg_type_and_handler_pair_t make_handler_with_arg(Handler_Type lambda)
Helper template for creation of event handler with actual argument.
Internal implementation details.
Helper templates for detection of lambda-type traits.
M * get_ptr(const intrusive_ptr_t< user_type_message_t< M > > &msg) noexcept
A helper function to get a const raw pointer from smart pointer.
M * get_ptr(const intrusive_ptr_t< M > &msg) noexcept
A helper function to get a const raw pointer from smart pointer.
Implementation details for implementation of rollback on exception helper.
Some reusable and low-level classes/functions which can be used in public header files.
auto make_message_instance(Args &&... args) -> std::unique_ptr< typename message_payload_type< Msg >::envelope_type >
A helper for allocate instance of a message.
Definition message.hpp:841
mhood_type_t
A special selector for mhood_t implementations.
Definition mhood.hpp:35
@ classical_signal
Message type is a classical signal derived from so_5::signal_t.
@ classical_message
Message type is a classical message derived from so_5::message_t.
@ user_type_message
Message type is not related to so_5::message_t.
auto do_with_rollback_on_exception(Main_Action main_action, Rollback_Action rollback_action) -> decltype(main_action())
Helper function for do some action with rollback in the case of an exception.
auto invoke_noexcept_code(L lambda) noexcept -> decltype(lambda())
method_arity
A special enumeration to specify arity of lambda-function or method.
@ nullary
Method or function has no arguments.
@ unary
Method or function has just one argument.
scope_exit_details::at_exit_t< L > at_scope_exit(L &&l)
Helper function for creation action to be performed at scope exit.
Dispatcher with single working thread.
Event dispatchers.
SO_5_FUNC optional< message_ref_t > message_to_be_inspected(const message_ref_t &msg_or_envelope)
Helper function for extraction of a payload from enveloped message.
SO_5_FUNC optional< payload_info_t > extract_payload_for_message_transformation(const message_ref_t &envelope)
Helper function for extraction of a payload from enveloped message.
access_context_t
Information about context on that enveloped message is handled.
Internal namespace with details of agent_t implementation.
Definition agent.hpp:462
Various helpers for message delivery tracing mechanism.
void safe_trace_state_leaving(const agent_t &state_owner, const state_t &state)
Helper for tracing the fact of leaving a state.
void safe_trace_state_entering(const agent_t &state_owner, const state_t &state)
Helper for tracing the fact of entering into a state.
void trace_deadletter_handler_search_result(const execution_demand_t &demand, const char *context_marker, const event_handler_data_t *search_result)
Helper for tracing the result of search of deadletter handler.
void trace_event_handler_search_result(const execution_demand_t &demand, const char *context_marker, const event_handler_data_t *search_result)
Helper for tracing the result of event handler search.
Details of SObjectizer run-time implementations.
Definition agent.cpp:905
Implementation details of error_logging facility.
so_5::timer_id_t schedule_timer(const std::type_index &subscription_type, message_ref_t msg, const mbox_t &mbox, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period)
Schedule periodic timer event.
void ensure_not_null(const delivery_filter_unique_ptr_t &ptr)
Helper function that throws if a pointer to delivery_filter is null.
Definition mbox.hpp:107
void single_timer(const std::type_index &subscription_type, message_ref_t msg, const mbox_t &mbox, std::chrono::steady_clock::duration pause)
Schedule single timer event.
void deliver_message(message_delivery_mode_t delivery_mode, abstract_message_box_t &target, std::type_index subscription_type, message_ref_t msg)
Deliver message.
Definition mbox.hpp:413
coop_shptr_t to_shptr_noexcept(const coop_handle_t &) noexcept
A helper function for unsafe extraction of shared_ptr to coop from coop_handle instance.
void deliver_signal(message_delivery_mode_t delivery_mode, abstract_message_box_t &target)
Deliver signal.
Definition mbox.hpp:445
void deliver_message(message_delivery_mode_t delivery_mode, abstract_message_box_t &target, std::type_index subscription_type, std::unique_ptr< Message > msg)
Deliver message.
Definition mbox.hpp:379
coop_shptr_t to_shptr(const coop_handle_t &)
A helper function for safe extraction of shared_ptr to coop from coop_handle instance.
Internal implementation of message limits related stuff.
Definition message.hpp:883
action_t make_action_for_message_transformer(Lambda &&transformator)
Helper function to make an action that performs message transformation.
SO_5_FUNC void redirect_reaction(const overlimit_context_t &ctx, const mbox_t &to)
Actual implementation of redirect message reaction.
SO_5_FUNC void abort_app_reaction(const overlimit_context_t &ctx)
Actual implementation of abort application reaction.
SO_5_FUNC void drop_message_reaction(const overlimit_context_t &ctx)
Actual implementation of drop message reaction.
action_t make_action_for_signal_transformer(Lambda &&transformator)
Helper function to make an action that performs signal transformation.
SO_5_FUNC void transform_reaction(const overlimit_context_t &ctx, const mbox_t &to, const std::type_index &msg_type, const message_ref_t &message)
Actual implementation of transform reaction.
All stuff related to message limits.
Definition message.hpp:862
void accept_one_indicator(description_container_t &to, const log_then_abort_app_indicator_t< M, L > &indicator)
Helper function for accepting log_then_abort_app_indicator and storing the corresponding description ...
void accept_indicators(description_container_t &)
void accept_indicators(description_container_t &to, I &&indicator, Args &&... others)
Helper function for constructing limits description from a series of limit indicators.
void accept_one_indicator(description_container_t &to, const drop_indicator_t< M > &indicator)
Helper function for accepting drop_indicator and storing the corresponding description into the limit...
void accept_one_indicator(description_container_t &to, transform_indicator_t< M > indicator)
Helper function for accepting transform_indicator and storing the corresponding description into the ...
void accept_one_indicator(description_container_t &to, const abort_app_indicator_t< M > &indicator)
Helper function for accepting abort_app_indicator and storing the corresponding description into the ...
void accept_one_indicator(description_container_t &to, redirect_indicator_t< Msg, Lambda > indicator)
Helper function for accepting redirect_indicator and storing the corresponding description into the l...
Public part of message delivery tracing mechanism.
Helpers for working with priorities.
Definition priority.hpp:73
const priority_t p0
Definition priority.hpp:79
const priority_t p5
Definition priority.hpp:84
void for_each_priority(Lambda l)
Does enumeration of all priorities.
Definition priority.hpp:193
const priority_t p7
Definition priority.hpp:86
const priority_t p3
Definition priority.hpp:82
const priority_t p6
Definition priority.hpp:85
const priority_t p1
Definition priority.hpp:80
const priority_t p2
Definition priority.hpp:81
priority_t prev(priority_t p)
Get the previous priority value.
Definition priority.hpp:155
bool has_prev(priority_t p)
Is there lower priority?
Definition priority.hpp:143
const priority_t default_priority
Default priority value.
Definition priority.hpp:97
priority_t next(priority_t p)
Get the next priority value.
Definition priority.hpp:128
const priority_t p4
Definition priority.hpp:83
bool has_next(priority_t p)
Is there higher priority?
Definition priority.hpp:116
const unsigned int total_priorities_count
Total count of priorities.
Definition priority.hpp:105
All stuff related to run-time monitoring and statistics.
Private part of message limit implementation.
Definition agent.cpp:33
std::size_t to_size_t(priority_t priority)
Helper function for conversion from priority to size_t.
Definition priority.hpp:48
const int rc_nullptr_as_result_of_user_mbox_factory
nullptr returned by user-provided mbox factory.
Definition ret_code.hpp:468
SO_5_FUNC subscription_storage_factory_t flat_set_based_subscription_storage_factory(std::size_t initial_capacity)
Factory for subscription storage based on sorted std::vector.
const int rc_disp_create_failed
Unable to create a dispatcher.
Definition ret_code.hpp:97
const int rc_layer_not_binded_to_so_env
The layer is not bound to the SObjectizer Environment.
Definition ret_code.hpp:152
message_delivery_mode_t
Possible modes of message/signal delivery.
Definition types.hpp:172
const int rc_coop_define_agent_failed
Cooperation couldn't be registered.
Definition ret_code.hpp:74
priority_t to_priority_t(std::size_t v)
Helper function for conversion from size_t to priority.
Definition priority.hpp:62
void ensure_message_with_actual_data(const Msg *m)
A special checker to guarantee that the message is an instance of the message_t (not signal_t) and ha...
Definition message.hpp:539
const int rc_state_nesting_is_too_deep
Nesting of agent states is too deep.
Definition ret_code.hpp:59
const int rc_agent_incompatible_type_conversion
It is impossible to make a cast to that type.
Definition ret_code.hpp:36
const int rc_initial_substate_already_defined
Initial substate for a composite state is already defined.
Definition ret_code.hpp:66
const int rc_unable_to_start_extra_layer
Layer initialization is failed.
Definition ret_code.hpp:164
SO_5_FUNC subscription_storage_factory_t default_subscription_storage_factory()
Factory for default subscription storage object.
mbox_type_t
Type of the message box.
Definition mbox.hpp:163
const int rc_negative_value_for_pause
An attempt to use negative value for pause argument for delayed or periodic message/signal.
Definition ret_code.hpp:270
const int rc_prepared_select_is_active_now
An attempt to activate prepared-select when an operation on that prepared-select object is already ac...
Definition ret_code.hpp:418
void ensure_not_signal()
A special compile-time checker to guarantee that the message class is not a signal class.
Definition message.hpp:517
const int rc_msg_chain_overflow
Definition ret_code.hpp:203
const int rc_coop_is_not_in_registered_state
An attempt to do something with coop that is not in registered state.
Definition ret_code.hpp:395
agent_context_t operator+(agent_context_t ctx, message_limit::abort_app_indicator_t< M > limit)
const int rc_mutable_msg_cannot_be_periodic
An attempt to send mutable message as a periodic message.
Definition ret_code.hpp:241
const int rc_cannot_set_stop_guard_when_stop_is_started
An attempt to set up a new stop_guard when the stop operation is already in progress.
Definition ret_code.hpp:259
constexpr unsigned int max_redirection_deep
Maximum deep of message redirections.
const int rc_no_preallocated_resources_for_agent
There are no resources that must have been in place for an agent in advance.
Definition ret_code.hpp:481
const int rc_transfer_to_state_loop
A loop in transfer_to_state detected.
Definition ret_code.hpp:337
exception_reaction_t
A reaction of SObjectizer to an exception from agent event.
Definition agent.hpp:65
@ abort_on_exception
Execution of application must be aborted immediatelly.
Definition agent.hpp:67
@ inherit_exception_reaction
Exception reaction should be inherited from SO Environment.
Definition agent.hpp:81
@ ignore_exception
Exception should be ignored and agent should continue its work.
Definition agent.hpp:75
@ deregister_coop_on_exception
Definition agent.hpp:73
@ shutdown_sobjectizer_on_exception
Definition agent.hpp:70
SO_5_FUNC error_logger_shptr_t create_stderr_logger()
A factory for creating error_logger implemenation which uses std::stderr as log stream.
void ensure_not_mutable_signal()
A special compile-time checker to guarantee that S is not a mutable signal.
Definition message.hpp:563
const int rc_coop_already_destroyed
An attempt to get a pointer to already destroyed cooperation.
Definition ret_code.hpp:384
agent_context_t operator+(agent_context_t ctx, so_5::priority_t agent_priority)
demands_handling_on_dereg_t
How pending demands should be handled on deregistration.
@ skip
Pending demands have to be skipped.
@ normal
Pending demands have to be handled as usual.
const int rc_agent_name_too_long
Length of an agent name is too large.
Definition ret_code.hpp:519
current_thread_id_t null_current_thread_id()
Get NULL thread id.
const thread_safety_t not_thread_safe
Shorthand for thread unsafety indicator.
Definition types.hpp:62
const int rc_msg_chain_is_full
Attempt to push a message to full message queue.
Definition ret_code.hpp:193
priority_t
Definition of supported priorities.
Definition priority.hpp:28
const thread_safety_t thread_safe
Shorthand for thread safety indicator.
Definition types.hpp:69
const int rc_operation_enabled_only_on_agent_working_thread
An attempt to perform an operation which is enabled only on agent's working thread.
Definition ret_code.hpp:44
const int rc_autoshutdown_must_be_enabled
An attempt to launch environment with autoshutdown disabled in conditions where autoshutdown must be ...
Definition ret_code.hpp:227
const int rc_agent_is_not_the_state_owner
Agent doesn't own this state.
Definition ret_code.hpp:108
const int rc_scenario_must_be_completed
Testing scenario must be completed before an attempt to do the current operation.
Definition ret_code.hpp:367
const int rc_extensible_select_is_active_now
An attempt to modify or activate extensible-select when an operation on that extensible-select object...
Definition ret_code.hpp:410
const int rc_agent_unknown_state
Trying to switch to the unknown state.
Definition ret_code.hpp:30
message_mutability_t
A enum with variants of message mutability or immutability.
Definition types.hpp:94
std::thread::id raw_id_from_current_thread_id(const current_thread_id_t &w)
Get the raw thread id from current_thread_id.
infinite_wait_indication
A type for special marker for infitite waiting on service request or on receive from mchain.
const int rc_trying_to_add_extra_layer_that_already_exists_in_extra_list
The layer is already bound to the SObjectizer Environment as an extra layer.
Definition ret_code.hpp:161
const int rc_several_limits_for_one_message_type
An attempt to define several limits for one message type.
Definition ret_code.hpp:130
const int rc_layer_does_not_exist
A layer with the specified type doesn't exist.
Definition ret_code.hpp:167
const int rc_invalid_time_limit_for_state
Invalid value of time limit for an agent's state.
Definition ret_code.hpp:539
const int rc_agent_to_disp_binding_failed
Binding of agent to dispatcher failed.
Definition ret_code.hpp:81
thread_safety_t
Thread safety indicator.
Definition types.hpp:50
@ unsafe
Not thread safe.
@ safe
Thread safe.
const int rc_priority_quote_illegal_value
Illegal value of quote for a priority.
Definition ret_code.hpp:174
const int rc_several_handlers_for_one_message_type
Attempt to define several handlers for one msg_type.
Definition ret_code.hpp:206
SO_5_FUNC subscription_storage_factory_t hash_table_based_subscription_storage_factory()
Factory for default subscription storage based on std::unordered_map.
const int rc_msg_chain_doesnt_support_subscriptions
Attempt to make subscription for message chain.
Definition ret_code.hpp:196
intrusive_ptr_t< Derived > make_agent_ref(Derived *agent)
Helper function template for the creation of smart pointer to an agent.
Definition agent.hpp:3567
constexpr demands_handling_on_dereg_t skip_demands_on_dereg
Marker that tells that pending demands have to be skipped on deregistration.
const infinite_wait_indication infinite_wait
A special indicator for infinite waiting on service request or on receive from mchain.
decltype(auto) introduce_child_coop(agent_t &owner, Args &&... args)
A simple way for creating and registering child cooperation.
const int rc_stored_msg_inspection_result_not_found
There is no stored msg inspection result in the testing scenario.
Definition ret_code.hpp:526
message_kind_t
A enum with variants of message kinds.
Definition types.hpp:109
@ user_type_message
Message is an user type message.
@ enveloped_msg
Message is an envelope with some other message inside.
agent_context_t operator+(agent_context_t ctx, message_limit::drop_indicator_t< M > limit)
const int rc_empty_agent_name
Name for an agent can't be empty.
Definition ret_code.hpp:512
const int rc_agent_deactivated
Agent can't change state because the agent is already deactivated.
Definition ret_code.hpp:432
no_wait_indication
A type for special marker for no waiting on service request or on receive from mchain.
SO_5_FUNC void swap(name_for_agent_t &a, name_for_agent_t &b) noexcept
Definition agent.cpp:150
const int rc_stored_state_name_not_found
There is no stored state name in the testing scenario.
Definition ret_code.hpp:374
mbox_id_t null_mbox_id()
Default value for null mbox_id.
Definition types.hpp:39
const int rc_another_state_switch_in_progress
An attempt to switch agent state when another switch operation is in progress.
Definition ret_code.hpp:216
work_thread_activity_tracking_t
Values for dispatcher's work thread activity tracking.
Definition types.hpp:75
@ unspecified
Tracking mode is specified elsewhere.
const no_wait_indication no_wait
A special indicator for no waiting on service request or on receive from mchain.
const int rc_unable_to_define_new_step
New step can't be defined if testing scenario is already started or finished.
Definition ret_code.hpp:359
const int rc_msg_tracing_disabled
Message delivery tracing is disabled and cannot be used.
Definition ret_code.hpp:182
message_ownership_t
Type of ownership of a message instance inside message_holder.
const int rc_unable_to_register_coop_during_shutdown
It is impossible to register cooperation during SObjectizer Environment shutdown.
Definition ret_code.hpp:89
intrusive_ptr_t(std::unique_ptr< T >) -> intrusive_ptr_t< T >
agent_context_t operator+(agent_context_t ctx, demands_handling_on_dereg_t handling_mode)
coop_unique_holder_t create_child_coop(coop_handle_t parent, Args &&... args)
A simple way for creating child cooperation when there is a reference to the parent cooperation objec...
msink_t SO_5_FUNC wrap_to_msink(const mbox_t &mbox, priority_t sink_priority=prio::p0)
Helper for wrapping an existing mbox into message_sink.
Definition mbox.cpp:109
delivery_possibility_t
Result of checking delivery posibility.
Definition mbox.hpp:39
const int rc_no_initial_substate
An attempt to change agent state to a new composite state which have no initial state defined.
Definition ret_code.hpp:52
const int rc_unable_to_join_thread_by_itself
An attempt to call join() from the joinable thread itself.
Definition ret_code.hpp:402
SO_5_FUNC subscription_storage_factory_t adaptive_subscription_storage_factory(std::size_t threshold, const subscription_storage_factory_t &small_storage_factory, const subscription_storage_factory_t &large_storage_factory)
Factory for adaptive subscription storage.
const int rc_agent_has_no_cooperation
Agent is not bound to a cooperation.
Definition ret_code.hpp:33
const int rc_null_message_data
Null message data.
Definition ret_code.hpp:144
const int rc_illegal_subscriber_for_mpsc_mbox
An attempt to create illegal subscription to mpsc_mbox.
Definition ret_code.hpp:115
const int rc_msg_chain_is_empty
Attempt to get message from empty message queue.
Definition ret_code.hpp:190
outliving_reference_t< const T > outliving_const(T const &r)
Make outliving_reference wrapper for const reference.
decltype(auto) introduce_child_coop(coop_handle_t parent, Args &&... args)
A simple way for creating and registering child cooperation when there is a reference to parent coop.
const int rc_unknown_exception_type
An exception of unknown type is caught.
Definition ret_code.hpp:556
void ensure_signal()
A special compile-time checker to guarantee that the Msg is derived from the signal_t.
Definition message.hpp:584
void ensure_classical_message()
A special compile-time checker to guarantee that Msg is derived from message_t.
Definition message.hpp:607
SO_5_FUNC subscription_storage_factory_t vector_based_subscription_storage_factory(std::size_t initial_capacity)
Factory for subscription storage based on unsorted std::vector.
transformed_message_t< Msg > make_transformed(mbox_t mbox, Args &&... args)
Helper function for creation of an instance of transformed_message_t.
disp_binder_shptr_t make_default_disp_binder(environment_t &env)
Create an instance of the default dispatcher binder.
const int rc_msg_chain_doesnt_support_delivery_filters
Attempt to set delivery_filter for message chain.
Definition ret_code.hpp:199
const int rc_environment_error
so_environment launch is failed.
Definition ret_code.hpp:24
outliving_reference_t< const T > outliving_const(outliving_reference_t< T > r)
Make outliving_reference wrapper for const reference.
SO_5_FUNC subscription_storage_factory_t map_based_subscription_storage_factory()
Factory for subscription storage based on std::map.
const int rc_empty_name
The empty name doesn't allowed.
Definition ret_code.hpp:532
const int rc_unexpected_error
Unclassified error.
Definition ret_code.hpp:559
SO_5_FUNC subscription_storage_factory_t adaptive_subscription_storage_factory(std::size_t threshold)
Factory for adaptive subscription storage.
agent_context_t operator+(environment_t &env, Option arg)
A plus operator for creating agent_context object from a reference to Environment and single agent tu...
agent_context_t operator+(agent_context_t ctx, message_limit::redirect_indicator_t< M, L > limit)
coop_unique_holder_t create_child_coop(agent_t &owner, Args &&... args)
A simple way for creating child cooperation.
agent_context_t operator+(agent_context_t ctx, message_limit::log_then_abort_app_indicator_t< M, L > limit)
agent_context_t operator+(agent_context_t ctx, subscription_storage_factory_t factory)
const int rc_attempt_to_cast_to_envelope_on_nullptr
An attempt to cast message to message envelope when a pointer to message is NULL.
Definition ret_code.hpp:351
const int rc_evt_handler_already_provided
A handler for that event/mbox/state is already registered.
Definition ret_code.hpp:105
agent_context_t operator+(agent_context_t ctx, name_for_agent_t agent_name)
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
const int rc_trying_to_add_extra_layer_that_already_exists_in_default_list
The layer is already bound to the SObjectizer Environment as a default layer.
Definition ret_code.hpp:158
event_handler_kind_t
Kind of an event handler.
Definition types.hpp:154
const int rc_disp_binder_already_set_for_agent
The dispatcher binder is already set for the agent.
Definition ret_code.hpp:492
current_thread_id_t query_current_thread_id()
Get the ID of the current thread.
const int rc_nullptr_as_delivery_filter_pointer
nullptr can't be passed as delivery_filter.
Definition ret_code.hpp:454
const int rc_not_implemented
Feature or method has no implementation yet.
Definition ret_code.hpp:546
const int rc_message_has_no_limit_defined
An attempt to create subscription to message without predefined limit for that message type.
Definition ret_code.hpp:123
const int rc_negative_value_for_period
An attempt to use negative value for period argument for periodic message/signal.
Definition ret_code.hpp:280
outliving_reference_t< T > outliving_mutable(T &r)
Make outliving_reference wrapper for mutable reference.
const int rc_mpsc_mbox_expected
An instance of MPSC mbox is expected as custom direct mbox.
Definition ret_code.hpp:443
transformed_message_t< Msg > make_transformed(mbox_t mbox, message_holder_t< Msg, Ownership > msg_holder)
Helper function for creation of an instance of transformed_message_t.
const int rc_subscription_to_mutable_msg_from_mpmc_mbox
An attempt to make subscription on mutable message from MPMC mbox.
Definition ret_code.hpp:251
const int rc_trying_to_add_nullptr_extra_layer
Unable to bind a layer by the null pointer to it.
Definition ret_code.hpp:155
agent_context_t operator+(agent_context_t ctx, message_limit::transform_indicator_t< M > limit)
const int rc_no_disp_binder_for_agent
The dispatcher binder is not set for the agent yet.
Definition ret_code.hpp:505
Type for case when agent has user-provided name.
Type for case when agent has no user-provided name.
SO_5_FUNC std::array< char, c_string_size > make_c_string() const noexcept
Make a c-string with text representation of a value.
Definition agent.cpp:39
static constexpr std::string_view c_string_prefix
Prefix to be used for string representation.
static constexpr std::size_t c_string_size
static constexpr std::string_view c_string_suffix
Suffix to be used for string representation.
void operator()(const pointer_only_t &v) const
void operator()(const actual_name_t &v) const
std::string operator()(const pointer_only_t &v) const
std::string operator()(const actual_name_t &v) const
A simple metafunction that always "returns" false.
static constexpr const bool value
A helper template for create an argument for event handler in the case when argument is passed as val...
Check whether T is a non-static member function pointer.
A detector of lambda argument type if the checked type is lambda.
A detector that type is a lambda or functional object.
Detector of plain type without const/volatile modifiers.
static R call_with_arg(R(*l)(M), M m)
Helper for calling a lambda.
static R call_with_arg(R(*l)(M), M m)
Helper for calling a lambda.
static R call_without_arg(L l)
Helper for calling a lambda.
static R call_with_arg(L l, M m)
Helper for calling a lambda.
Detector of lambda result and argument type.
static std::unique_ptr< E > make(Args &&... args)
Definition message.hpp:803
A helper template to detect type of message from the format of an event handler.
A meta-function for selection of type of accessors mixin.
A meta-function for selection a base of message_holder implementation in compile-time.
static const constexpr message_mutability_t mutability
Definition message.hpp:414
static const constexpr message_mutability_t mutability
Definition message.hpp:425
Detector of message type traits in dependency of message immutability or mutability.
Definition message.hpp:398
static const constexpr message_mutability_t mutability
Definition message.hpp:403
A special detector of message immutability/mutability.
Definition mhood.hpp:442
static constexpr const message_mutability_t mutability
Definition mhood.hpp:443
A special selector of message hood type.
Definition mhood.hpp:425
static constexpr const mhood_type_t mhood_type
Definition mhood.hpp:426
bool operator<(const msg_type_and_handler_pair_t &o) const
Comparison (strictly less than).
msg_type_and_handler_pair_t(std::type_index msg_type)
Constructor for the case when only msg_type is known.
friend void swap(msg_type_and_handler_pair_t &a, msg_type_and_handler_pair_t &b) noexcept
Swap operation.
msg_type_and_handler_pair_t(const msg_type_and_handler_pair_t &o)
Copy constructor.
msg_type_and_handler_pair_t & operator=(msg_type_and_handler_pair_t &&o) noexcept
Move operator.
std::type_index m_msg_type
Type of a message or signal.
msg_type_and_handler_pair_t(msg_type_and_handler_pair_t &&o) noexcept
Move constructor.
event_handler_method_t m_handler
A handler for processing this message or signal.
msg_type_and_handler_pair_t(std::type_index msg_type, event_handler_method_t handler, message_mutability_t mutability)
Initializing constructor.
bool operator==(const msg_type_and_handler_pair_t &o) const
Comparison (strictly equal).
msg_type_and_handler_pair_t & operator=(const msg_type_and_handler_pair_t &o)
Copy operator.
message_mutability_t m_mutability
What message is expected by handler: mutable or immutable.
static void exec(Main_Action main_action, rollbacker_t< Rollback_Action > &rollback)
static Result exec(Main_Action main_action, rollbacker_t< Rollback_Action > &rollback)
Internal details of SObjectizer Environment object.
A description of event execution demand.
mbox_id_t m_mbox_id
ID of mbox.
void call_handler(current_thread_id_t thread_id)
Helper method to simplify demand execution.
demand_handler_pfn_t m_demand_handler
Demand handler.
agent_t * m_receiver
Receiver of demand.
message_ref_t m_message_ref
Event incident.
execution_demand_t() noexcept
Default constructor.
const message_limit::control_block_t * m_limit
Optional message limit for that message.
execution_demand_t(agent_t *receiver, const message_limit::control_block_t *limit, mbox_id_t mbox_id, std::type_index msg_type, message_ref_t message_ref, demand_handler_pfn_t demand_handler) noexcept
std::type_index m_msg_type
Type of the message.
A helper class for temporary setting and then dropping the ID of the current working thread.
Definition agent.hpp:474
working_thread_id_sentinel_t(so_5::current_thread_id_t &id_var, so_5::current_thread_id_t value_to_set)
Definition agent.hpp:477
Information about event_handler and its properties.
thread_safety_t m_thread_safety
Is event handler thread safe or not.
event_handler_kind_t m_kind
Kind of this event handler.
Helper class to be used as a comparator for msinks.
bool operator()(const msink_t &a, const msink_t &b) const noexcept
static std::pair< const abstract_sink_owner_t *, so_5::priority_t > safe_get_pair(const msink_t &from) noexcept
A helper function to call appropriate constructor of resulting type in dependence of message or signa...
static Result make(mbox_t mbox, Args &&... args)
Create a message instance.
Helper for marking initial substate of composite state.
Definition state.hpp:57
initial_substate_of(state_t &parent_state)
Definition state.hpp:60
A helper class for checking that message is a classical message derived from message_t class.
Definition message.hpp:480
A helper class for checking that message is a mutable message.
Definition message.hpp:496
A helper class for checking that message is a signal.
Definition message.hpp:463
A helper for detection presence of message of user type.
Definition message.hpp:443
const mbox_t & m_mbox
Mbox to which message will be delivered.
const message_ref_t & m_msg
Message to be sent after timeout.
std::chrono::steady_clock::duration m_period
Period of the delivery repetition for periodic messages.
std::chrono::steady_clock::duration m_pause
Timeout before the first delivery.
const std::type_index & m_msg_type
Message type.
const mbox_t & m_mbox
Mbox to which message will be delivered.
const std::type_index & m_msg_type
Message type.
std::chrono::steady_clock::duration m_pause
Timeout before the delivery.
const message_ref_t & m_msg
Message to be sent after timeout.
Message limit with reaction 'abort the application'.
const unsigned int m_limit
Max count of waiting messages.
abort_app_indicator_t(unsigned int limit)
Initializing constructor.
A control block for one message limit.
Definition message.hpp:976
action_t m_action
Limit overflow reaction.
Definition message.hpp:984
std::atomic_uint m_count
The current count of the messages of that type.
Definition message.hpp:981
control_block_t(unsigned int limit, action_t action)
Initializing constructor.
Definition message.hpp:987
unsigned int m_limit
Limit value.
Definition message.hpp:978
static const control_block_t * none()
A special indicator about absence of control_block.
Definition message.hpp:1023
control_block_t & operator=(const control_block_t &o)
Copy operator.
Definition message.hpp:1009
static void decrement(const control_block_t *limit)
Definition message.hpp:1028
control_block_t(const control_block_t &o)
Copy constructor.
Definition message.hpp:997
A description of one message limit.
std::type_index m_msg_type
Type of message.
description_t(std::type_index msg_type, unsigned int limit, action_t action)
Initializing constructor.
unsigned int m_limit
Max count of waiting messages.
action_t m_action
Reaction to overload.
Message limit with reaction 'drop new message'.
drop_indicator_t(unsigned int limit)
Initializing constructor.
const unsigned int m_limit
Max count of waiting messages.
static void call(const overlimit_context_t &ctx, L action)
Helper class for calling pre-abort action.
static void call(const overlimit_context_t &ctx, L action)
Helper class for calling pre-abort action.
Message limit with reaction 'abort the application' and the possibility to call additional lambda bef...
const L m_lambda
Lambda for some last actions.
const unsigned int m_limit
Max count of waiting messages.
log_then_abort_app_indicator_t(unsigned int limit, L lambda)
Initializing constructor.
A mixin with message limit definition methods.
static drop_indicator_t< Msg > limit_then_drop(unsigned int limit)
A helper function for creating drop_indicator.
static redirect_indicator_t< Msg, Lambda > limit_then_redirect(unsigned int limit, Lambda dest_getter)
A helper function for creating redirect_indicator.
static transform_indicator_t< Source > limit_then_transform(unsigned int limit, Lambda &&transformator)
A helper function for creating transform_indicator.
static log_then_abort_app_indicator_t< M, L > limit_then_abort(unsigned int limit, L lambda)
A helper function for creating log_then_abort_app_indicator.
static abort_app_indicator_t< Msg > limit_then_abort(unsigned int limit)
A helper function for creating abort_app_indicator.
static auto limit_then_redirect(unsigned int limit, mbox_t destination)
A helper function for creating redirect_indicator.
static transformed_message_t< Msg > make_transformed(mbox_t mbox, Args &&... args)
Helper method for creating message transformation result.
static auto limit_then_transform(unsigned int limit, Lambda &&transformator)
A helper function for creating transform_indicator.
Description of context for overlimit action.
Definition message.hpp:895
const message_delivery_mode_t m_delivery_mode
Delivery mode for message delivery attempt.
Definition message.hpp:907
overlimit_context_t(mbox_id_t mbox_id, message_delivery_mode_t delivery_mode, const agent_t &receiver, const control_block_t &limit, unsigned int reaction_deep, const std::type_index &msg_type, const message_ref_t &message, const impl::action_msg_tracer_t *msg_tracer)
Initializing constructor.
Definition message.hpp:937
const mbox_id_t m_mbox_id
ID of mbox which is used for message delivery.
Definition message.hpp:901
const control_block_t & m_limit
Control block for message limit.
Definition message.hpp:913
const unsigned int m_reaction_deep
The current deep of overlimit reaction recursion.
Definition message.hpp:916
const agent_t & m_receiver
Receiver of the message (or enveloped message).
Definition message.hpp:910
const std::type_index & m_msg_type
Type of message to be delivered.
Definition message.hpp:919
const message_ref_t & m_message
A message (or enveloped message) to be delivered.
Definition message.hpp:922
const impl::action_msg_tracer_t * m_msg_tracer
An optional pointer to tracer object for message delivery tracing.
Definition message.hpp:933
Indication that a message must be redirected on overlimit.
Lambda m_destination_getter
A lambda/functional object which returns mbox for redirection.
const unsigned int m_limit
Max count of waiting messages.
redirect_indicator_t(unsigned int limit, Lambda destination_getter)
Initializing constructor.
An indicator of transform reaction on message overlimit.
transform_indicator_t(unsigned int limit, action_t action)
Initializing constructor.
static constexpr message_mutability_t mutability()
Helper for getting message mutability flag.
Definition message.hpp:762
static payload_type & payload_reference(message_t &msg)
Helper for getting a const reference to payload part.
Definition message.hpp:753
static constexpr const bool is_signal
Is it a signal type or message type.
Definition message.hpp:716
static payload_type * extract_payload_ptr(message_ref_t &msg)
Helper for extraction of pointer to payload part.
Definition message.hpp:732
static envelope_type * extract_envelope_ptr(message_ref_t &msg)
Helper for extraction of pointer to envelope part.
Definition message.hpp:745
static std::type_index subscription_type_index()
Type ID for subscription.
Definition message.hpp:720
Implementation details for message_payload_type.
Definition message.hpp:626
static constexpr message_mutability_t mutability()
Helper for getting message mutability flag.
Definition message.hpp:684
static payload_type & payload_reference(message_t &msg)
Helper for getting a const reference to payload part.
Definition message.hpp:676
static envelope_type * extract_envelope_ptr(message_ref_t &msg)
Helper for extraction of pointer to envelope part.
Definition message.hpp:668
static std::type_index subscription_type_index()
Type ID for subscription.
Definition message.hpp:642
static constexpr const bool is_signal
Is it a signal type or message type.
Definition message.hpp:638
static payload_type * extract_payload_ptr(message_ref_t &msg)
Helper for extraction of pointer to payload part.
Definition message.hpp:657
A helper class for detection of payload type of message.
Definition message.hpp:783
Helper type with method to be mixed into agent class.
static name_for_agent_t name_for_agent(std::string_view name)
A helper factory for making name_for_agent_t instance.
activation_data_t(timer_id_t timer, steady_clock::time_point expiration_point)
Definition agent.cpp:336
steady_clock::time_point m_expiration_point
Timeout of timeout expiration.
Definition agent.cpp:334
timer_id_t m_timer
ID of delayed timeout signal.
Definition agent.cpp:331
Helper for marking a substate of composite state.
Definition state.hpp:89
state_t * m_parent_state
Definition state.hpp:90
substate_of(state_t &parent_state)
Definition state.hpp:92
Template class for representing object of user type as a message.
Definition message.hpp:315
user_type_message_t(T &&o)
Initialization from temporary T object.
Definition message.hpp:340
kind_t so5_message_kind() const noexcept override
Detect the kind of the message.
Definition message.hpp:346
user_type_message_t(T &o)
Initialization from non-const T object.
Definition message.hpp:335
T m_payload
Instance of user message.
Definition message.hpp:321
user_type_message_t(const T &o)
Initialization from const T object.
Definition message.hpp:330
user_type_message_t(Args &&... args)
Initializing constructor.
Definition message.hpp:325
#define SO_5_VERSION_PATCH
Definition version.hpp:45
#define SO_5_VERSION_MAJOR
Definition version.hpp:24
#define SO_5_VERSION_MAKE(major, minor, patch)
Definition version.hpp:58
#define SO_5_VERSION_MINOR
Definition version.hpp:34