SObjectizer 5.8
Loading...
Searching...
No Matches
simple_mtsafe_st_env_infrastructure.cpp
Go to the documentation of this file.
1/*
2 * SObjectizer-5
3 */
4
5/*!
6 * \file
7 * \brief A very simple multithreaded-safe single thread
8 * environment infrastructure.
9 *
10 * \since v.5.5.19
11 */
12
13#include <so_5/impl/st_env_infrastructure_reuse.hpp>
14
15#include <so_5/impl/run_stage.hpp>
16#include <so_5/impl/internal_env_iface.hpp>
17
18#include <so_5/impl/final_dereg_chain_helpers.hpp>
19
20#include <so_5/disp/reuse/data_source_prefix_helpers.hpp>
21
22#include <so_5/environment.hpp>
23#include <so_5/send_functions.hpp>
24
25#include <so_5/details/at_scope_exit.hpp>
26#include <so_5/details/sync_helpers.hpp>
27
28namespace so_5 {
29
30namespace env_infrastructures {
31
32namespace simple_mtsafe {
33
34namespace impl {
35
36namespace helpers {
37
38template< typename Action >
39auto
41 std::unique_lock< std::mutex > & acquired_lock,
42 Action && action ) -> decltype(action())
43 {
44 acquired_lock.unlock();
45 auto relock_again = so_5::details::at_scope_exit( [&acquired_lock]{
46 acquired_lock.lock();
47 } );
48
49 return action();
50 }
51
52} /* namespace helpers */
53
54//! A short name for namespace with run-time stats stuff.
55namespace stats = ::so_5::stats;
56
57//! A short name for namespace with reusable stuff.
58namespace reusable = ::so_5::env_infrastructures::st_reusable_stuff;
59
60/*!
61 * \brief Status of the main thread on which environment is working.
62 *
63 * Main thread can handle some events or can sleep and wait for new events.
64 *
65 * \since v.5.5.19
66 */
68 {
69 working,
71 };
72
73/*!
74 * \brief A bunch of sync objects which need to be shared between
75 * various parts of env_infrastructure.
76 *
77 * \since v.5.5.19
78 */
80 {
81 //! Main lock for environment infrastructure.
82 std::mutex m_lock;
83 //! A condition to sleep on when no activities to handle.
84 std::condition_variable m_wakeup_condition;
85
86 //! The current status of the main thread.
88 };
89
90/*!
91 * \note
92 * Mutex from sync_objects must be already acquired!
93 */
94inline void
96 {
97 if( main_thread_status_t::waiting == sync_objects.m_status )
98 sync_objects.m_wakeup_condition.notify_one();
99 }
100
101//
102// shutdown_status_t
103//
104using shutdown_status_t = reusable::shutdown_status_t;
105
106//
107// event_queue_impl_t
108//
109/*!
110 * \brief Implementation of event_queue interface for this type of
111 * environment infrastructure.
112 *
113 * \since v.5.5.19
114 */
115class event_queue_impl_t final : public so_5::event_queue_t
116 {
117 public :
118 //! Type for representation of statistical data for this event queue.
119 struct stats_t
120 {
121 //! The current size of the demands queue.
122 std::size_t m_demands_count;
123 };
124
126 : m_sync_objects( sync_objects )
127 {}
128
129 /*!
130 * \note
131 * This method locks the main mutex by itself.
132 */
133 void
134 push( execution_demand_t demand ) override
135 {
136 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
137
138 m_demands.push_back( std::move(demand) );
139
141 }
142
143 /*!
144 * \note
145 * Delegates the work to the push() method.
146 */
147 void
149 {
150 this->push( std::move(demand) );
151 }
152
153 /*!
154 * \note
155 * Delegates the work to the push() method.
156 *
157 * \attention
158 * Terminates the whole application if the push() throws.
159 */
160 void
161 push_evt_finish( execution_demand_t demand ) noexcept override
162 {
163 this->push( std::move(demand) );
164 }
165
166 /*!
167 * \note
168 * This method locks the main mutex by itself.
169 */
170 stats_t
172 {
173 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
174
175 return { m_demands.size() };
176 }
177
178 //! Type for result of extraction operation.
179 enum class pop_result_t
180 {
181 extracted,
183 };
184
185 /*!
186 * \note
187 * NOTE: this method must be called only when main thread's mutex
188 * is locked.
189 */
191 pop( execution_demand_t & receiver ) noexcept
192 {
193 if( !m_demands.empty() )
194 {
195 receiver = std::move(m_demands.front());
196 m_demands.pop_front();
198 }
199
201 }
202
203 private :
205
207 };
208
209//
210// coop_repo_t
211//
212/*!
213 * \brief Implementation of coop_repository for
214 * simple thread-safe single-threaded environment infrastructure.
215 *
216 * \since v.5.5.19
217 */
218using coop_repo_t = reusable::coop_repo_t;
219
220//
221// disp_ds_name_parts_t
222//
223/*!
224 * \brief A special class for generation of names for dispatcher data sources.
225 *
226 * \since v.5.5.19
227 */
229 {
230 static constexpr const char *
231 disp_type_part() noexcept { return "mtsafe_st_env"; }
232 };
233
234//
235// default_dispatcher_t
236//
237/*!
238 * \brief An implementation of dispatcher to be used in
239 * places where default dispatcher is needed.
240 *
241 * \tparam Activity_Tracker a type of activity tracker to be used
242 * for run-time statistics.
243 *
244 * \since v.5.5.19
245 */
246template< typename Activity_Tracker >
247using default_dispatcher_t =
248 reusable::default_dispatcher_t<
249 event_queue_impl_t,
250 Activity_Tracker,
252
253//
254// stats_controller_t
255//
256/*!
257 * \brief Implementation of stats_controller for that type of
258 * single-threaded environment.
259 *
260 * \since v.5.5.19
261 */
262using stats_controller_t =
263 reusable::stats_controller_t< so_5::details::actual_lock_holder_t<> >;
264
265//
266// env_infrastructure_t
267//
268/*!
269 * \brief Default implementation of multithreaded environment infrastructure.
270 *
271 * \tparam Activity_Tracker A type for tracking activity of main working thread.
272 *
273 * \since v.5.5.19
274 */
275template< typename Activity_Tracker >
278 {
279 public :
281 //! Environment to work in.
282 environment_t & env,
283 //! Factory for timer manager.
284 timer_manager_factory_t timer_factory,
285 //! Error logger necessary for timer_manager.
286 error_logger_shptr_t error_logger,
287 //! Cooperation action listener.
288 coop_listener_unique_ptr_t coop_listener,
289 //! Mbox for distribution of run-time stats.
290 mbox_t stats_distribution_mbox );
291
292 void
293 launch( env_init_t init_fn ) override;
294
295 void
296 stop() noexcept override;
297
298 [[nodiscard]]
300 make_coop(
301 coop_handle_t parent,
302 disp_binder_shptr_t default_binder ) override;
303
304 [[nodiscard]]
307 coop_unique_holder_t coop ) override;
308
309 void
311 coop_shptr_t coop ) noexcept override;
312
313 bool
315 coop_shptr_t coop ) noexcept override;
316
319 const std::type_index & type_wrapper,
320 const message_ref_t & msg,
321 const mbox_t & mbox,
322 std::chrono::steady_clock::duration pause,
323 std::chrono::steady_clock::duration period ) override;
324
325 void
327 const std::type_index & type_wrapper,
328 const message_ref_t & msg,
329 const mbox_t & mbox,
330 std::chrono::steady_clock::duration pause ) override;
331
332 stats::controller_t &
333 stats_controller() noexcept override;
334
335 stats::repository_t &
336 stats_repository() noexcept override;
337
340
342 query_timer_thread_stats() override;
343
344 disp_binder_shptr_t
345 make_default_disp_binder() override;
346
347 private :
349
350 //! All sync objects to be shared between different parts.
352
353 /*!
354 * \brief The chain of coops for the final deregistration.
355 *
356 * \since v.5.8.0
357 */
359
360 //! Status of shutdown procedure.
361 shutdown_status_t m_shutdown_status{ shutdown_status_t::not_started };
362
363 //! A collector for elapsed timers.
364 reusable::actual_elapsed_timers_collector_t m_timers_collector;
365
366 //! A timer manager to be used.
367 timer_manager_unique_ptr_t m_timer_manager;
368
369 //! Queue for execution_demands which must be handled on the main thread.
370 event_queue_impl_t m_event_queue;
371
372 //! Repository of registered coops.
373 coop_repo_t m_coop_repo;
374
375 //! Actual activity tracker for main working thread.
376 Activity_Tracker m_activity_tracker;
377
378 //! Dispatcher to be used as default dispatcher.
379 /*!
380 * \note
381 * Has an actual value only inside launch() method.
382 */
383 std::shared_ptr< default_dispatcher_t< Activity_Tracker > > m_default_disp;
384
385 //! Stats controller for this environment.
386 stats_controller_t m_stats_controller;
387
388 void
390 env_init_t init_fn );
391
392 void
394 env_init_t init_fn );
395
396 void
397 run_main_loop() noexcept;
398
399 void
401 std::unique_lock< std::mutex > & acquired_lock ) noexcept;
402
403 void
405 std::unique_lock< std::mutex > & acquired_lock ) noexcept;
406
407 void
409 std::unique_lock< std::mutex > & acquired_lock ) noexcept;
410
411 void
413 std::unique_lock< std::mutex > & acquired_lock ) noexcept;
414 };
415
416template< typename Activity_Tracker >
418 environment_t & env,
419 timer_manager_factory_t timer_factory,
420 error_logger_shptr_t error_logger,
421 coop_listener_unique_ptr_t coop_listener,
422 mbox_t stats_distribution_mbox )
423 : m_env( env )
425 timer_factory(
426 std::move(error_logger),
429 , m_coop_repo( outliving_mutable(env), std::move(coop_listener) )
431 std::move(stats_distribution_mbox),
432 stats::impl::st_env_stuff::next_turn_mbox_t::make(m_env) )
433 {}
434
435template< typename Activity_Tracker >
436void
437env_infrastructure_t< Activity_Tracker >::launch( env_init_t init_fn )
438 {
439 run_default_dispatcher_and_go_further( std::move(init_fn) );
440 }
441
442template< typename Activity_Tracker >
443void
444env_infrastructure_t< Activity_Tracker >::stop() noexcept
445 {
446 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
447
448 if( shutdown_status_t::not_started == m_shutdown_status )
449 {
450 m_shutdown_status = shutdown_status_t::must_be_started;
452 }
453 }
454
455template< typename Activity_Tracker >
457env_infrastructure_t< Activity_Tracker >::make_coop(
458 coop_handle_t parent,
459 disp_binder_shptr_t default_binder )
460 {
462 std::move(parent),
463 std::move(default_binder) );
464 }
465
466template< typename Activity_Tracker >
470 {
471 return m_coop_repo.register_coop( std::move(coop) );
472 }
473
474template< typename Activity_Tracker >
475void
477 coop_shptr_t coop ) noexcept
478 {
479 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
480
481 m_final_dereg_chain.append( std::move(coop) );
482
484 }
485
486template< typename Activity_Tracker >
487bool
489 coop_shptr_t coop ) noexcept
490 {
491 return m_coop_repo.final_deregister_coop( std::move(coop) )
493 }
494
495template< typename Activity_Tracker >
498 const std::type_index & type_wrapper,
499 const message_ref_t & msg,
500 const mbox_t & mbox,
501 std::chrono::steady_clock::duration pause,
502 std::chrono::steady_clock::duration period )
503 {
504 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
505
506 auto timer = m_timer_manager->schedule(
507 type_wrapper,
508 mbox,
509 msg,
510 pause,
511 period );
512
514
515 return timer;
516 }
517
518template< typename Activity_Tracker >
519void
521 const std::type_index & type_wrapper,
522 const message_ref_t & msg,
523 const mbox_t & mbox,
524 std::chrono::steady_clock::duration pause )
525 {
526 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
527
529 type_wrapper,
530 mbox,
531 msg,
532 pause,
533 std::chrono::milliseconds::zero() );
534
536 }
537
538template< typename Activity_Tracker >
539stats::controller_t &
540env_infrastructure_t< Activity_Tracker >::stats_controller() noexcept
541 {
542 return m_stats_controller;
543 }
544
545template< typename Activity_Tracker >
546stats::repository_t &
547env_infrastructure_t< Activity_Tracker >::stats_repository() noexcept
548 {
549 return m_stats_controller;
550 }
551
552template< typename Activity_Tracker >
555 {
556 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
557
558 const auto stats = m_coop_repo.query_stats();
559
564 };
565 }
566
567template< typename Activity_Tracker >
570 {
571 std::lock_guard< std::mutex > lock( m_sync_objects.m_lock );
572
574 }
575
576template< typename Activity_Tracker >
577disp_binder_shptr_t
579 {
580 return { m_default_disp };
581 }
582
583template< typename Activity_Tracker >
584void
586 env_init_t init_fn )
587 {
588 ::so_5::impl::run_stage(
589 "run_default_dispatcher",
590 [this] {
591 m_default_disp = std::make_shared<
592 default_dispatcher_t< Activity_Tracker > >(
595 outliving_mutable(m_activity_tracker) );
596 },
597 [this] {
598 m_default_disp.reset();
599 },
600 [this, init_func=std::move(init_fn)] {
601 run_user_supplied_init_and_do_main_loop( std::move(init_func) );
602 } );
603 }
604
605template< typename Activity_Tracker >
606void
608 env_init_t init_fn )
609 {
610 /*
611 If init_fn throws an exception we can found ourselves
612 in a situation where there are some working coops.
613 Those coops should be correctly deregistered. It means
614 that we should usual main loop even in the case of
615 an exception from init_fn. But this main loop should
616 work only until all coops will be deregistered.
617
618 To do that we will catch an exception from init and
619 initiate shutdown even before the call to run_main_loop().
620 Then we call run_main_loop() and wail for its completion.
621 Then we reraise the exception caught.
622
623 Note that in this scheme run_main_loop() should be
624 noexcept function because otherwise we will loose the
625 initial exception from init_fn.
626 */
627 optional< std::exception_ptr > exception_from_init;
628 try
629 {
630 so_5::impl::wrap_init_fn_call( std::move(init_fn) );
631 }
632 catch( ... )
633 {
634 // We can't restore if there will be an exception.
635 so_5::details::invoke_noexcept_code( [&] {
636 // Store the content of the exception to reraise it later.
637 exception_from_init = std::current_exception();
638 // Execution should be stopped.
639 stop();
640 } );
641 }
642
643 // We don't expect exceptions from the main loop.
644 so_5::details::invoke_noexcept_code( [this] {
646 } );
647
648 // If there was an exception from init_fn this exception
649 // should be rethrown.
650 if( exception_from_init )
651 std::rethrow_exception( *exception_from_init );
652 }
653
654template< typename Activity_Tracker >
655void
656env_infrastructure_t< Activity_Tracker >::run_main_loop() noexcept
657 {
658 // Assume that waiting for new demands is started.
659 // This call is necessary because if there is a demand
660 // in event queue then m_activity_tracker.wait_stopped() will be
661 // called without previous m_activity_tracker.wait_started().
662 m_activity_tracker.wait_started();
663
664 // Acquire the main lock for the first time.
665 // It will be released and reacquired many times later.
666 std::unique_lock< std::mutex > lock( m_sync_objects.m_lock );
667 for(;;)
668 {
669 // The first step: all pending final deregs must be processed.
671
672 // There can be pending shutdown operation. It must be handled.
674 if( shutdown_status_t::completed == m_shutdown_status )
675 break;
676
677 // The next step: all timers must be converted to events.
679
680 // The last step: an attempt to process demand.
681 // Or sleep for some time until next demand arrived.
683 }
684 }
685
686template< typename Activity_Tracker >
687void
689 std::unique_lock< std::mutex > & acquired_lock ) noexcept
690 {
691 // This loop is necessary because it is possible that new
692 // final dereg demand will be added during processing of
693 // the current final dereg demand.
695 {
697
698 helpers::unlock_do_and_lock_again( acquired_lock,
699 [&head] {
701 } );
702 }
703 }
704
705template< typename Activity_Tracker >
706void
708 std::unique_lock< std::mutex > & acquired_lock ) noexcept
709 {
710 if( shutdown_status_t::must_be_started == m_shutdown_status )
711 {
712 // Shutdown procedure must be started.
713 m_shutdown_status = shutdown_status_t::in_progress;
714
715 // All registered cooperations must be deregistered now.
716 // We must unlock out main lock because there is a need to
717 // push a final event for deregisteing agents to event queue.
718 helpers::unlock_do_and_lock_again( acquired_lock,
719 [this] {
721 } );
722 }
723
724 if( shutdown_status_t::in_progress == m_shutdown_status )
725 {
726 // If there is no more live coops then shutdown must be completed.
728 m_shutdown_status = shutdown_status_t::completed;
729 }
730 }
731
732template< typename Activity_Tracker >
733void
735 std::unique_lock< std::mutex > & acquired_lock ) noexcept
736 {
737 // All expired timers must be collected.
739
741 // Actual handling of elapsed timers must be done
742 // on unlocked env_infrastructure.
743 // It is necessary because there can be an attempt to
744 // deliver delayed/periodic messages into event_queue of
745 // the default_dispatcher. But it is impossible to do if
746 // env_infrastructure's mutex is locked.
747 helpers::unlock_do_and_lock_again( acquired_lock,
748 [this] {
750 } );
751 }
752
753template< typename Activity_Tracker >
754void
756 std::unique_lock< std::mutex > & acquired_lock ) noexcept
757 {
758 execution_demand_t demand;
759 const auto pop_result = m_event_queue.pop( demand );
760 // If there is no demands we must go to sleep for some time...
761 if( event_queue_impl_t::pop_result_t::empty_queue == pop_result )
762 {
763 // ... but we should go to sleep only if there is no
764 // pending final deregistration actions.
766 {
767 // Tracking time for 'waiting' state must be turned on.
768 m_activity_tracker.wait_start_if_not_started();
769
770 const auto sleep_time =
772 std::chrono::minutes(1) );
773
775
777 acquired_lock,
778 sleep_time );
779
781 }
782 }
783 else
784 {
785 // Tracking time for 'waiting' must be turned off, but
786 // tracking time for 'working' must be tuned on and then off again.
787 m_activity_tracker.wait_stopped();
788 m_activity_tracker.work_started();
789 auto work_tracking_stopper = so_5::details::at_scope_exit(
790 [this]{ m_activity_tracker.work_stopped(); } );
791
792 // There is at least one demand to process.
793 helpers::unlock_do_and_lock_again( acquired_lock,
794 [this, &demand] {
795 m_default_disp->handle_demand( demand );
796 } );
797 }
798 }
799
800} /* namespace impl */
801
802//
803// simple_mtsafe_st_env_infrastructure_factory
804//
805SO_5_FUNC environment_infrastructure_factory_t
806factory( params_t && infrastructure_params )
807 {
808 using namespace impl;
809
810 return [infrastructure_params](
811 environment_t & env,
812 environment_params_t & env_params,
813 mbox_t stats_distribution_mbox )
814 {
815 environment_infrastructure_t * obj = nullptr;
816
817 auto timer_manager_factory =
818 infrastructure_params.timer_manager();
819
820 // Create environment infrastructure object in dependence of
821 // work thread activity tracking flag.
822 const auto tracking = env_params.work_thread_activity_tracking();
824 obj = new env_infrastructure_t< reusable::real_activity_tracker_t >(
825 env,
826 std::move(timer_manager_factory),
827 env_params.so5_error_logger(),
829 std::move(stats_distribution_mbox) );
830 else
831 obj = new env_infrastructure_t< reusable::fake_activity_tracker_t >(
832 env,
833 std::move(timer_manager_factory),
834 env_params.so5_error_logger(),
836 std::move(stats_distribution_mbox) );
837
838 return environment_infrastructure_unique_ptr_t(
839 obj,
841 };
842 }
843
844} /* namespace simple_mtsafe */
845
846} /* namespace env_infrastructures */
847
848} /* namespace so_5 */
Type of smart handle for a cooperation.
A special type that plays role of unique_ptr for coop.
Definition coop.hpp:1342
A class to be used as mixin with actual std::mutex instance inside.
Default implementation of multithreaded environment infrastructure.
std::shared_ptr< default_dispatcher_t< Activity_Tracker > > m_default_disp
Dispatcher to be used as default dispatcher.
stats::repository_t & stats_repository() noexcept override
Get stats repository for the environment.
void single_timer(const std::type_index &type_wrapper, const message_ref_t &msg, const mbox_t &mbox, std::chrono::steady_clock::duration pause) override
Initiate a delayed message.
reusable::actual_elapsed_timers_collector_t m_timers_collector
A collector for elapsed timers.
so_5::timer_id_t schedule_timer(const std::type_index &type_wrapper, const message_ref_t &msg, const mbox_t &mbox, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period) override
Initiate a timer (delayed or periodic message).
void launch(env_init_t init_fn) override
Do actual launch of SObjectizer's Environment.
coop_handle_t register_coop(coop_unique_holder_t coop) override
Register new cooperation.
void stop() noexcept override
Initiate a signal for shutdown of Environment.
so_5::impl::final_dereg_chain_holder_t m_final_dereg_chain
The chain of coops for the final deregistration.
void perform_shutdown_related_actions_if_needed(std::unique_lock< std::mutex > &acquired_lock) noexcept
main_thread_sync_objects_t m_sync_objects
All sync objects to be shared between different parts.
void try_handle_next_demand(std::unique_lock< std::mutex > &acquired_lock) noexcept
timer_thread_stats_t query_timer_thread_stats() override
Query run-time statistics for timer (thread or manager).
void process_final_deregs_if_any(std::unique_lock< std::mutex > &acquired_lock) noexcept
so_5::environment_infrastructure_t::coop_repository_stats_t query_coop_repository_stats() override
Query run-time statistics for cooperation repository.
coop_unique_holder_t make_coop(coop_handle_t parent, disp_binder_shptr_t default_binder) override
Create an instance of a new coop.
bool final_deregister_coop(coop_shptr_t coop) noexcept override
Do final actions of the cooperation deregistration.
event_queue_impl_t m_event_queue
Queue for execution_demands which must be handled on the main thread.
env_infrastructure_t(environment_t &env, timer_manager_factory_t timer_factory, error_logger_shptr_t error_logger, coop_listener_unique_ptr_t coop_listener, mbox_t stats_distribution_mbox)
disp_binder_shptr_t make_default_disp_binder() override
Create a binder for the default dispatcher.
void handle_expired_timers_if_any(std::unique_lock< std::mutex > &acquired_lock) noexcept
stats::controller_t & stats_controller() noexcept override
Get stats controller for the environment.
Activity_Tracker m_activity_tracker
Actual activity tracker for main working thread.
Parameters for simple thread-safe single-thread environment.
const timer_manager_factory_t & timer_manager() const
Getter for timer_manager factory.
coop_repo_t(outliving_reference_t< environment_t > env, coop_listener_unique_ptr_t coop_listener)
Initializing constructor.
An implementation of dispatcher to be used in places where default dispatcher is needed.
stats_controller_t(mbox_t distribution_mbox, mbox_t next_turn_mbox)
Initializing constructor.
An interface for environment_infrastructure entity.
static environment_infrastructure_deleter_fnptr_t default_deleter()
Default deleter for environment_infrastructure object.
Parameters for the SObjectizer Environment initialization.
coop_listener_unique_ptr_t so5_giveout_coop_listener()
Get cooperation listener.
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.
SObjectizer Environment.
An interface of event queue for agent.
coop_unique_holder_t make_coop(coop_handle_t parent, disp_binder_shptr_t default_binder)
Create an instance of a new coop.
void deregister_all_coop() noexcept
Deregisted all cooperations.
final_deregistration_result_t final_deregister_coop(coop_shptr_t coop) noexcept
Do final actions of the cooperation deregistration.
environment_infrastructure_t::coop_repository_stats_t query_stats()
Get the current statistic for run-time monitoring.
coop_handle_t register_coop(coop_unique_holder_t agent_coop)
Register cooperation.
Helper class for holding the current chain of coops for the final deregistration.
A public interface for control SObjectizer monitoring options.
static mbox_t make(environment_t &env)
Helper for simplify creation of that mboxes of that type.
An interface of data sources repository.
An indentificator for the timer.
Definition timers.hpp:73
virtual void schedule_anonymous(const std::type_index &type_index, const mbox_t &mbox, const message_ref_t &msg, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period)=0
Push anonymous delayed/periodic message to the timer queue.
virtual std::chrono::steady_clock::duration timeout_before_nearest_timer(std::chrono::steady_clock::duration default_timer)=0
Calculate time before the nearest timer (if any).
virtual void process_expired_timers()=0
Translation of expired timers into message sends.
virtual timer_id_t schedule(const std::type_index &type_index, const mbox_t &mbox, const message_ref_t &msg, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period)=0
Push delayed/periodic message to the timer queue.
virtual timer_thread_stats_t query_stats()=0
Get statistics for run-time monitoring.
#define SO_5_FUNC
Definition declspec.hpp:48
Some reusable and low-level classes/functions which can be used in public header files.
auto unlock_do_and_lock_again(std::unique_lock< std::mutex > &acquired_lock, Action &&action) -> decltype(action())
main_thread_status_t
A short name for namespace with run-time stats stuff.
void wakeup_if_waiting(main_thread_sync_objects_t &sync_objects)
Simple single-threaded environment infrastructure with thread safety.
SO_5_FUNC environment_infrastructure_factory_t factory(params_t &&params)
A factory for creation of simple thread-safe single-thread environment infrastructure object.
Various reusable stuff which can be used in implementation of single-threaded environment infrastruct...
shutdown_status_t
A short name for namespace with run-time stats stuff.
@ must_be_started
Shutdown must be started as soon as possible.
@ completed
Shutdown completed and work of environment must be finished.
@ in_progress
Shutdown is initiated but not finished yet.
Various implementations of environment_infrastructure.
Details of SObjectizer run-time implementations.
Definition agent.cpp:780
void process_final_dereg_chain(coop_shptr_t head) noexcept
Helper function that does proceesing of final dereg chain.
void wrap_init_fn_call(Init_Fn init_fn)
A special wrapper for calling init function.
Internal implementation of run-time monitoring and statistics related stuff.
All stuff related to run-time monitoring and statistics.
Private part of message limit implementation.
Definition agent.cpp:33
work_thread_activity_tracking_t
Values for dispatcher's work thread activity tracking.
Definition types.hpp:75
outliving_reference_t< T > outliving_mutable(T &r)
Make outliving_reference wrapper for mutable reference.
A special class for generation of names for dispatcher data sources.
A bunch of sync objects which need to be shared between various parts of env_infrastructure.
std::condition_variable m_wakeup_condition
A condition to sleep on when no activities to handle.
Statistical data for run-time monitoring of coop repository content.
std::size_t m_total_coop_count
Count of cooperations inside the environment.
A description of event execution demand.
Statistics for run-time monitoring.
Definition timers.hpp:120