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