SObjectizer-5 Extra
common.hpp
Go to the documentation of this file.
1 /*!
2  * \file
3  * \brief Common parts for Asio's env_infrastructures.
4  */
5 
6 #pragma once
7 
8 #include <so_5/impl/st_env_infrastructure_reuse.hpp>
9 
10 #include <asio.hpp>
11 
12 namespace so_5 {
13 
14 namespace extra {
15 
17 
18 namespace asio {
19 
20 namespace common {
21 
22 namespace helpers {
23 
24 //
25 // ensure_we_can_handle_this_timer_error_code
26 //
27 /*!
28  * \brief Helper function which checke error_code value.
29  *
30  * It returns normally if there is no an error or if the error
31  * is ::asio::error::operation_aborted.
32  */
33 void
35  const ::asio::error_code & ec )
36  {
37  if( ec && ::asio::error::operation_aborted != ec )
38  SO_5_THROW_EXCEPTION( rc_unexpected_error,
39  "Only asio::operation_aborted error code can be handled "
40  "by timer handler" );
41  }
42 
43 } /* namespace helpers */
44 
45 //
46 // singleshot_timer_holder_t
47 //
48 /*!
49  * \brief A main part of implementation of single-shot timer.
50  */
52  {
54 
55  //! Actual Asio's timer.
57  //! Type of message/signal to be delivered.
59  //! Instance of message to be delivered.
61  //! A destination mbox.
62  const mbox_t m_mbox;
63 
64  public :
65  //! Initializing constructor.
67  //! Asio's io_context to be used for timer.
68  ::asio::io_context & io_svc,
69  //! Type of message/signal to be delivered.
70  const std::type_index & type_index,
71  //! Message instance to be delivered.
72  const message_ref_t & msg,
73  //! A destination mbox.
74  const mbox_t & mbox )
75  : m_timer( io_svc )
77  , m_msg( msg )
78  , m_mbox( mbox )
79  {}
80 
81  //! Cancelation of the timer.
82  void
84  {
85  m_timer.cancel();
86  }
87 
88  //! Scheduling of timer.
89  void
91  //! A pause in message delivery.
92  std::chrono::steady_clock::duration pause )
93  {
94  intrusive_ptr_t< singleshot_timer_holder_t > self{ this };
95  m_timer.expires_after( pause );
96  m_timer.async_wait(
97  // Timer action shouldn't throw because we don't know
98  // how to repair it.
99  [self]( const ::asio::error_code & ec ) noexcept {
100  helpers::ensure_we_can_handle_this_timer_error_code( ec );
101  if( ::asio::error::operation_aborted == ec )
102  return;
103 
104  ::so_5::impl::mbox_iface_for_timers_t{ self->m_mbox }
105  .deliver_message_from_timer(
106  self->m_type_index,
107  self->m_msg );
108  } );
109  }
110  };
111 
112 //
113 // periodic_timer_holder_t
114 //
115 /*!
116  * \brief A main part of implementation of periodic timer.
117  *
118  * \note This class is very similar to singleshot_timer_holder_t, but
119  * these classes are not related to simplify implemenation of them.
120  */
122  {
124 
125  //! Actual Asio's timer.
127  //! Type of message/signal to be delivered.
129  //! Instance of message to be delivered.
131  //! A destination mbox.
132  const mbox_t m_mbox;
133  //! A repetition period for periodic message delivery.
135 
136  public :
138  //! Asio's io_context to be used for timer.
139  ::asio::io_context & io_svc,
140  //! Type of message/signal to be delivered.
141  const std::type_index & type_index,
142  //! Message instance to be delivered.
143  const message_ref_t & msg,
144  //! A destination mbox.
145  const mbox_t & mbox,
146  //! A repetition period for periodic message delivery.
147  std::chrono::steady_clock::duration period )
148  : m_timer( io_svc )
150  , m_msg( msg )
151  , m_mbox( mbox )
152  , m_period( period )
153  {}
154 
155  //! Cancelation of the timer.
156  void
158  {
159  m_timer.cancel();
160  }
161 
162  //! Scheduling of timer.
163  void
165  //! A pause in message delivery.
166  std::chrono::steady_clock::duration pause )
167  {
168  intrusive_ptr_t< periodic_timer_holder_t > self{ this };
169  m_timer.expires_after( pause );
170  m_timer.async_wait(
171  // Timer action shouldn't throw because we don't know
172  // how to repair it.
173  [self]( const ::asio::error_code & ec ) noexcept {
174  helpers::ensure_we_can_handle_this_timer_error_code( ec );
175  if( ::asio::error::operation_aborted == ec )
176  return;
177 
178  ::so_5::impl::mbox_iface_for_timers_t{ self->m_mbox }
179  .deliver_message_from_timer(
180  self->m_type_index,
181  self->m_msg );
182  self->schedule_from_now( self->m_period );
183  } );
184  }
185  };
186 
187 //
188 // actual_timer_t
189 //
190 /*!
191  * \brief A template for implementation of actual timer.
192  *
193  * \tparam Holder Type of actual timer data. Expected to be
194  * periodic_timer_holder_t or singleshot_timer_holder_t.
195  */
196 template< typename Holder >
197 class actual_timer_t : public timer_t
198  {
199  public :
200  using holder_t = Holder;
202 
204  holder_smart_ptr_t holder )
205  : m_holder( std::move(holder) )
206  {}
207  virtual ~actual_timer_t() override
208  {
209  release();
210  }
211 
212  virtual bool
213  is_active() const noexcept override
214  {
215  return m_holder;
216  }
217 
218  virtual void
219  release() noexcept override
220  {
221  if( m_holder )
222  {
223  m_holder->cancel();
224  m_holder.reset();
225  }
226  }
227 
228  private :
230  };
231 
232 } /* namespace common */
233 
234 } /* namespace asio */
235 
236 } /* namespace env_infrastructures */
237 
238 } /* namespace extra */
239 
240 } /* namespace so_5 */
const message_ref_t m_msg
Instance of message to be delivered.
Definition: common.hpp:60
const std::type_index m_type_index
Type of message/signal to be delivered.
Definition: common.hpp:128
virtual bool is_active() const noexcept override
Definition: common.hpp:213
Ranges for error codes of each submodules.
Definition: details.hpp:13
periodic_timer_holder_t(::asio::io_context &io_svc, const std::type_index &type_index, const message_ref_t &msg, const mbox_t &mbox, std::chrono::steady_clock::duration period)
Definition: common.hpp:137
::asio::steady_timer m_timer
Actual Asio&#39;s timer.
Definition: common.hpp:126
void schedule_from_now(std::chrono::steady_clock::duration pause)
Scheduling of timer.
Definition: common.hpp:164
A template for implementation of actual timer.
Definition: common.hpp:197
void schedule_from_now(std::chrono::steady_clock::duration pause)
Scheduling of timer.
Definition: common.hpp:90
const std::type_index m_type_index
Type of message/signal to be delivered.
Definition: common.hpp:58
void ensure_we_can_handle_this_timer_error_code(const ::asio::error_code &ec)
Helper function which checke error_code value.
Definition: common.hpp:34
::asio::steady_timer m_timer
Actual Asio&#39;s timer.
Definition: common.hpp:56
singleshot_timer_holder_t(::asio::io_context &io_svc, const std::type_index &type_index, const message_ref_t &msg, const mbox_t &mbox)
Initializing constructor.
Definition: common.hpp:66
const std::chrono::steady_clock::duration m_period
A repetition period for periodic message delivery.
Definition: common.hpp:134
const message_ref_t m_msg
Instance of message to be delivered.
Definition: common.hpp:130