SObjectizer  5.8
Loading...
Searching...
No Matches
timers.cpp
Go to the documentation of this file.
1/*
2 SObjectizer 5.
3*/
4
5/*!
6 \file
7 \since
8 v.5.5.0
9
10 \brief Timers and tools for working with timers.
11*/
12
13#include <so_5/details/abort_on_fatal_error.hpp>
14
15#include <so_5/impl/mbox_iface_for_timers.hpp>
16
17#include <so_5/timers.hpp>
18
19#include <so_5/3rd_party/timertt/all.hpp>
20
21namespace so_5
22{
23
25{
26
27//
28// actual_timer_t
29//
30/*!
31 * \brief An actual implementation of timer interface.
32 *
33 * \note
34 * Since v.5.5.19 this template can be used with timer_thread and
35 * with timer_manager.
36 *
37 * \tparam Timer A type of timertt-based thread/manager which implements timers.
38 *
39 * \since v.5.5.0
40 */
41template< class Timer >
42class actual_timer_t : public timer_t
43 {
44 public :
45 //! The actual type of timer holder for timertt.
46 using timer_holder_t = timertt::timer_object_holder<
47 typename Timer::thread_safety >;
48
49 //! Initialized constructor.
51 Timer * thread )
52 : m_thread( thread )
53 , m_timer( thread->allocate() )
54 {}
55 virtual ~actual_timer_t() noexcept override
56 {
57 release();
58 }
59
60 timer_holder_t &
61 timer_holder() noexcept
62 {
63 return m_timer;
64 }
65
66 virtual bool
67 is_active() const noexcept override
68 {
69 return (m_thread != nullptr);
70 }
71
72 virtual void
73 release() noexcept override
74 {
75 if( m_thread )
76 {
78 m_thread = nullptr;
79 m_timer.reset();
80 }
81 }
82
83 private :
84 //! Timer thread for the timer.
85 /*!
86 * nullptr means that timer is deactivated.
87 */
88 Timer * m_thread;
89
90 //! Underlying timer object reference.
91 timer_holder_t m_timer;
92 };
93
94//
95// timer_action_for_timer_thread_t
96//
97/*!
98 * \brief A functor to be used as timer action in implementation
99 * of timer thread.
100 *
101 * \since
102 * v.5.5.20
103 */
105 {
107 mbox_t m_mbox;
108 message_ref_t m_msg;
109
110 public:
112 std::type_index type_index,
113 mbox_t mbox,
114 message_ref_t msg )
116 , m_mbox( std::move(mbox) )
117 , m_msg( std::move(msg) )
118 {}
119
120 void
121 operator()() noexcept
122 {
123 ::so_5::impl::mbox_iface_for_timers_t{ m_mbox }
124 .deliver_message_from_timer( m_type_index, m_msg );
125 }
126 };
127
128//
129// actual_thread_t
130//
131/*!
132 * \since
133 * v.5.5.0
134 *
135 * \brief An actual implementation of timer thread.
136 *
137 * \tparam Timer_Thread A type of timertt-based thread which implements timers.
138 */
139template< class Timer_Thread >
141 {
142 using timer_demand_t = actual_timer_t< Timer_Thread >;
143
144 public :
145 //! Initializing constructor.
147 //! Real timer thread.
148 std::unique_ptr< Timer_Thread > thread )
149 : m_thread( std::move( thread ) )
150 {}
151
152 virtual void
153 start() override
154 {
155 m_thread->start();
156 }
157
158 virtual void
159 finish() override
160 {
162 }
163
164 virtual timer_id_t
166 const std::type_index & type_index,
167 const mbox_t & mbox,
168 const message_ref_t & msg,
169 std::chrono::steady_clock::duration pause,
170 std::chrono::steady_clock::duration period ) override
171 {
173
175 pause,
176 period,
178
179 return timer_id_t( timer.release() );
180 }
181
182 virtual void
184 const std::type_index & type_index,
185 const mbox_t & mbox,
186 const message_ref_t & msg,
187 std::chrono::steady_clock::duration pause,
188 std::chrono::steady_clock::duration period ) override
189 {
191 pause,
192 period,
194 }
195
197 query_stats() override
198 {
200
204 };
205 }
206
207 private :
209 };
210
211//
212// timer_action_for_timer_manager_t
213//
214/*!
215 * \brief A functor to be used as timer action in implementation
216 * of timer thread.
217 *
218 * \since
219 * v.5.5.20
220 */
222 {
226 mbox_t m_mbox;
227 message_ref_t m_msg;
228
229 public:
232 collector,
233 std::type_index type_index,
234 mbox_t mbox,
235 message_ref_t msg )
238 , m_mbox( std::move(mbox) )
239 , m_msg( std::move(msg) )
240 {}
241
242 void
243 operator()() noexcept
244 {
245 m_collector.get().accept( m_type_index, m_mbox, m_msg );
246 }
247 };
248
249//
250// actual_manager_t
251//
252/*!
253 * \brief An actual implementation of timer_manager.
254 *
255 * \tparam Timer_Manager A type of timertt-based manager which implements timers.
256 *
257 * \since
258 * v.5.5.19
259 */
260template< class Timer_Manager >
262 {
263 using timer_demand_t = actual_timer_t< Timer_Manager >;
264
265 public :
266 //! Initializing constructor.
268 //! Real timer thread.
269 std::unique_ptr< Timer_Manager > manager,
270 //! Collector for elapsed timers.
272 collector )
273 : m_manager( std::move( manager ) )
275 {}
276
277 virtual void
282
289
290 virtual timer_id_t
292 const std::type_index & type_index,
293 const mbox_t & mbox,
294 const message_ref_t & msg,
295 std::chrono::steady_clock::duration pause,
296 std::chrono::steady_clock::duration period ) override
297 {
299
301 pause,
302 period,
305
306 return timer_id_t( timer.release() );
307 }
308
309 virtual void
311 const std::type_index & type_index,
312 const mbox_t & mbox,
313 const message_ref_t & msg,
314 std::chrono::steady_clock::duration pause,
315 std::chrono::steady_clock::duration period ) override
316 {
318 pause,
319 period,
322 }
323
324 virtual bool
325 empty() override
326 {
327 return m_manager->empty();
328 }
329
331 query_stats() override
332 {
334
338 };
339 }
340
341 private :
345 };
346
347//
348// error_logger_for_timertt_t
349//
350/*!
351 * \since
352 * v.5.5.0
353 *
354 * \brief Type of error_logger for timertt stuff.
355 */
357
358//
359// create_error_logger_for_timertt
360//
361
362#if defined(__clang__)
363#pragma clang diagnostic push
364#pragma clang diagnostic ignored "-Wmissing-prototypes"
365#endif
366
369 {
370 // NOTE: if this logger throws then timertt will catch the exception
371 // and terminate the application.
372 // It's normal because timertt calls this logger right before calling
373 // std::abort() in the cases when timertt can't recover from
374 // previous failures.
375 return [logger]( const std::string & msg ) {
376 SO_5_LOG_ERROR( *logger, stream ) {
377 stream << "error inside timer_thread: " << msg;
378 }
379 };
380 }
381
382#if defined(__clang__)
383#pragma clang diagnostic pop
384#endif
385
386//
387// exception_handler_for_timertt_t
388//
389/*!
390 * \since
391 * v.5.5.0
392 *
393 * \brief Type of actor_exception_handler for timertt stuff.
394 */
396 std::function< void(const std::exception &) >;
397
398//
399// create_exception_handler_for_timertt
400//
401
402#if defined(__clang__)
403#pragma clang diagnostic push
404#pragma clang diagnostic ignored "-Wmissing-prototypes"
405#endif
406
410 {
411 return [logger]( const std::exception & x ) {
412 so_5::details::abort_on_fatal_error( [&] {
413 SO_5_LOG_ERROR( *logger, stream ) {
414 stream << "exception has been thrown and caught inside "
415 "timer_thread, application will be aborted. "
416 "Exception: " << x.what();
417 }
418 } );
419 };
420 }
421
425 {
426 return [logger]( const std::exception & x ) {
427 so_5::details::abort_on_fatal_error( [&] {
428 SO_5_LOG_ERROR( *logger, stream ) {
429 stream << "exception has been thrown and caught inside "
430 "timer_manager, application will be aborted. "
431 "Exception: " << x.what();
432 }
433 } );
434 };
435 }
436
437#if defined(__clang__)
438#pragma clang diagnostic pop
439#endif
440
441/*!
442 * \name Short synonyms for timertt templates.
443 * \{
444 */
445//! timer_wheel thread type.
450
451//! timer_heap thread type.
456
457//! timer_list thread type.
462
463//! timer_wheel manager type.
469
470//! timer_heap manager type.
476
477//! timer_list manager type.
483/*!
484 * \}
485 */
486
487} /* namespace timers_details */
488
492 {
493 using timertt_thread_t = timers_details::timer_wheel_thread_t;
494
495 return create_timer_wheel_thread(
496 std::move(logger),
497 timertt_thread_t::default_wheel_size(),
498 timertt_thread_t::default_granularity() );
499 }
500
504 unsigned int wheel_size,
506 {
507 using timertt_thread_t = timers_details::timer_wheel_thread_t;
508 using namespace timers_details;
509
510 std::unique_ptr< timertt_thread_t > thread(
511 new timertt_thread_t(
512 wheel_size,
513 granuality,
514 create_error_logger_for_timertt( logger ),
515 create_exception_handler_for_timertt_thread( logger ) ) );
516
517 return timer_thread_unique_ptr_t(
518 new actual_thread_t< timertt_thread_t >( std::move( thread ) ) );
519 }
520
524 {
525 using timertt_thread_t = timers_details::timer_heap_thread_t;
526
527 return create_timer_heap_thread(
528 std::move(logger),
529 timertt_thread_t::default_initial_heap_capacity() );
530 }
531
536 {
537 using timertt_thread_t = timers_details::timer_heap_thread_t;
538 using namespace timers_details;
539
540 std::unique_ptr< timertt_thread_t > thread(
541 new timertt_thread_t(
542 initial_heap_capacity,
543 create_error_logger_for_timertt( logger ),
544 create_exception_handler_for_timertt_thread( logger ) ) );
545
546 return timer_thread_unique_ptr_t(
547 new actual_thread_t< timertt_thread_t >( std::move( thread ) ) );
548 }
549
553 {
554 using timertt_thread_t = timers_details::timer_list_thread_t;
555 using namespace timers_details;
556
557 std::unique_ptr< timertt_thread_t > thread(
558 new timertt_thread_t(
559 create_error_logger_for_timertt( logger ),
560 create_exception_handler_for_timertt_thread( logger ) ) );
561
562 return timer_thread_unique_ptr_t(
563 new actual_thread_t< timertt_thread_t >( std::move( thread ) ) );
564 }
565
571 {
572 using timertt_manager_t = timers_details::timer_wheel_manager_t;
573
574 return create_timer_wheel_manager(
575 std::move(logger),
576 collector,
577 timertt_manager_t::default_wheel_size(),
578 timertt_manager_t::default_granularity() );
579 }
580
586 unsigned int wheel_size,
588 {
589 using timertt_manager_t = timers_details::timer_wheel_manager_t;
590 using namespace timers_details;
591
592 auto manager = std::make_unique< timertt_manager_t >(
593 wheel_size,
594 granuality,
595 create_error_logger_for_timertt( logger ),
596 create_exception_handler_for_timertt_manager( logger ) );
597
598 return std::make_unique< actual_manager_t< timertt_manager_t > >(
599 std::move( manager ),
600 collector );
601 }
602
608 {
609 using timertt_manager_t = timers_details::timer_heap_manager_t;
610
611 return create_timer_heap_manager(
612 std::move(logger),
613 collector,
614 timertt_manager_t::default_initial_heap_capacity() );
615 }
616
623 {
624 using timertt_manager_t = timers_details::timer_heap_manager_t;
625 using namespace timers_details;
626
627 auto manager = std::make_unique< timertt_manager_t >(
628 initial_heap_capacity,
629 create_error_logger_for_timertt( logger ),
630 create_exception_handler_for_timertt_manager( logger ) );
631
632 return std::make_unique< actual_manager_t< timertt_manager_t > >(
633 std::move( manager ),
634 collector );
635 }
636
642 {
643 using timertt_manager_t = timers_details::timer_list_manager_t;
644 using namespace timers_details;
645
646 auto manager = std::make_unique< timertt_manager_t >(
647 create_error_logger_for_timertt( logger ),
648 create_exception_handler_for_timertt_manager( logger ) );
649
650 return std::make_unique< actual_manager_t< timertt_manager_t > >(
651 std::move( manager ),
652 collector );
653 }
654
655} /* namespace so_5 */
Helper class for indication of long-lived reference via its type.
Definition outliving.hpp:98
An indentificator for the timer.
Definition timers.hpp:82
An interface for collector of elapsed timers.
Definition timers.hpp:452
Timer manager interface.
Definition timers.hpp:425
A base class for timer identificator.
Definition timers.hpp:47
Timer thread interface.
Definition timers.hpp:162
An actual implementation of timer_manager.
Definition timers.cpp:262
virtual timer_thread_stats_t query_stats() override
Get statistics for run-time monitoring.
Definition timers.cpp:331
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) override
Push anonymous delayed/periodic message to the timer queue.
Definition timers.cpp:310
actual_manager_t(std::unique_ptr< Timer_Manager > manager, outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector)
Initializing constructor.
Definition timers.cpp:267
outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > m_collector
Definition timers.cpp:344
virtual bool empty() override
Definition timers.cpp:325
virtual void process_expired_timers() override
Translation of expired timers into message sends.
Definition timers.cpp:278
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) override
Push delayed/periodic message to the timer queue.
Definition timers.cpp:291
std::unique_ptr< Timer_Manager > m_manager
Definition timers.cpp:342
virtual std::chrono::steady_clock::duration timeout_before_nearest_timer(std::chrono::steady_clock::duration default_timer) override
Calculate time before the nearest timer (if any).
Definition timers.cpp:284
An actual implementation of timer thread.
Definition timers.cpp:141
std::unique_ptr< Timer_Thread > m_thread
Definition timers.cpp:208
virtual timer_thread_stats_t query_stats() override
Get statistics for run-time monitoring.
Definition timers.cpp:197
virtual void start() override
Launch timer.
Definition timers.cpp:153
actual_thread_t(std::unique_ptr< Timer_Thread > thread)
Initializing constructor.
Definition timers.cpp:146
virtual void finish() override
Finish timer and wait for full stop.
Definition timers.cpp:159
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) override
Push delayed/periodic message to the timer queue.
Definition timers.cpp:165
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) override
Push anonymous delayed/periodic message to the timer queue.
Definition timers.cpp:183
An actual implementation of timer interface.
Definition timers.cpp:43
timer_holder_t & timer_holder() noexcept
Definition timers.cpp:61
actual_timer_t(Timer *thread)
Initialized constructor.
Definition timers.cpp:50
virtual void release() noexcept override
Release the timer event.
Definition timers.cpp:73
timer_holder_t m_timer
Underlying timer object reference.
Definition timers.cpp:91
virtual ~actual_timer_t() noexcept override
Definition timers.cpp:55
virtual bool is_active() const noexcept override
Is this timer event is active?
Definition timers.cpp:67
Timer * m_thread
Timer thread for the timer.
Definition timers.cpp:88
A functor to be used as timer action in implementation of timer thread.
Definition timers.cpp:222
timer_action_for_timer_manager_t(outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector, std::type_index type_index, mbox_t mbox, message_ref_t msg)
Definition timers.cpp:230
outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > m_collector
Definition timers.cpp:224
A functor to be used as timer action in implementation of timer thread.
Definition timers.cpp:105
timer_action_for_timer_thread_t(std::type_index type_index, mbox_t mbox, message_ref_t msg)
Definition timers.cpp:111
An intrusive smart pointer to timer demand.
#define SO_5_FUNC
Definition declspec.hpp:48
#define SO_5_LOG_ERROR(logger, var_name)
A special macro for helping error logging.
Timers implementation details.
Definition timers.cpp:25
exception_handler_for_timertt_t create_exception_handler_for_timertt_thread(const error_logger_shptr_t &logger)
Definition timers.cpp:408
exception_handler_for_timertt_t create_exception_handler_for_timertt_manager(const error_logger_shptr_t &logger)
Definition timers.cpp:423
error_logger_for_timertt_t create_error_logger_for_timertt(const error_logger_shptr_t &logger)
Definition timers.cpp:368
Private part of message limit implementation.
Definition agent.cpp:33
SO_5_FUNC timer_manager_unique_ptr_t create_timer_heap_manager(error_logger_shptr_t logger, outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector, std::size_t initial_heap_capacity)
Create timer manager based on timer_heap mechanism.
Definition timers.cpp:618
SO_5_FUNC timer_thread_unique_ptr_t create_timer_wheel_thread(error_logger_shptr_t logger)
Create timer thread based on timer_wheel mechanism.
Definition timers.cpp:490
SO_5_FUNC timer_thread_unique_ptr_t create_timer_heap_thread(error_logger_shptr_t logger, std::size_t initial_heap_capacity)
Create timer thread based on timer_heap mechanism.
Definition timers.cpp:533
SO_5_FUNC timer_thread_unique_ptr_t create_timer_list_thread(error_logger_shptr_t logger)
Create timer thread based on timer_list mechanism.
Definition timers.cpp:551
SO_5_FUNC timer_manager_unique_ptr_t create_timer_list_manager(error_logger_shptr_t logger, outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector)
Create timer thread based on timer_list mechanism.
Definition timers.cpp:638
SO_5_FUNC timer_manager_unique_ptr_t create_timer_wheel_manager(error_logger_shptr_t logger, outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector)
Create timer manager based on timer_wheel mechanism.
Definition timers.cpp:567
SO_5_FUNC timer_manager_unique_ptr_t create_timer_wheel_manager(error_logger_shptr_t logger, outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector, unsigned int wheel_size, std::chrono::steady_clock::duration granuality)
Create timer manager based on timer_wheel mechanism.
Definition timers.cpp:582
SO_5_FUNC timer_manager_unique_ptr_t create_timer_heap_manager(error_logger_shptr_t logger, outliving_reference_t< timer_manager_t::elapsed_timers_collector_t > collector)
Create timer manager based on timer_heap mechanism.
Definition timers.cpp:604
SO_5_FUNC timer_thread_unique_ptr_t create_timer_wheel_thread(error_logger_shptr_t logger, unsigned int wheel_size, std::chrono::steady_clock::duration granuality)
Create timer thread based on timer_wheel mechanism.
Definition timers.cpp:502
SO_5_FUNC timer_thread_unique_ptr_t create_timer_heap_thread(error_logger_shptr_t logger)
Create timer thread based on timer_heap mechanism.
Definition timers.cpp:522
Top-level project's namespace.
Statistics for run-time monitoring.
Definition timers.hpp:136