1 /*
2 SObjectizer 5.
3 */
4
5 /*!
6 * \file
7 * \brief Functions for creating and binding of the single thread dispatcher
8 * with priority support.
9 *
10 * \since
11 * v.5.5.8
12 */
13
14 #pragma once
15
16 #include <so_5/declspec.hpp>
17
18 #include <so_5/disp_binder.hpp>
19
20 #include <so_5/priority.hpp>
21
22 #include <so_5/disp/mpsc_queue_traits/pub.hpp>
23
24 #include <so_5/disp/reuse/work_thread_activity_tracking.hpp>
25
26 #include <string>
27
28 namespace so_5 {
29
30 namespace disp {
31
32 namespace prio_one_thread {
33
34 namespace strictly_ordered {
35
36 /*!
37 * \brief Alias for namespace with traits of event queue.
38 *
39 * \since
40 * v.5.5.10
41 */
42 namespace queue_traits = so_5::disp::mpsc_queue_traits;
43
44 //
45 // disp_params_t
46 //
47 /*!
48 * \brief Parameters for a dispatcher.
49 *
50 * \since
51 * v.5.5.10
52 */
53 class disp_params_t
54 : public so_5::disp::reuse::work_thread_activity_tracking_flag_mixin_t< disp_params_t >
55 {
56 using activity_tracking_mixin_t = so_5::disp::reuse::
57 work_thread_activity_tracking_flag_mixin_t< disp_params_t >;
58
59 public :
60 //! Default constructor.
61 disp_params_t() = default;
62
swap(disp_params_t & a,disp_params_t & b)63 friend inline void swap( disp_params_t & a, disp_params_t & b ) noexcept
64 {
65 swap(
66 static_cast< activity_tracking_mixin_t & >(a),
67 static_cast< activity_tracking_mixin_t & >(b) );
68
69 swap( a.m_queue_params, b.m_queue_params );
70 }
71
72 //! Setter for queue parameters.
73 disp_params_t &
set_queue_params(queue_traits::queue_params_t p)74 set_queue_params( queue_traits::queue_params_t p )
75 {
76 m_queue_params = std::move(p);
77 return *this;
78 }
79
80 //! Tuner for queue parameters.
81 /*!
82 * Accepts lambda-function or functional object which tunes
83 * queue parameters.
84 \code
85 namespace prio_disp = so_5::disp::prio_one_thread::strictly_ordered;
86 auto disp = prio_disp::make_dispatcher( env,
87 "my_prio_disp",
88 prio_disp::disp_params_t{}.tune_queue_params(
89 []( prio_disp::queue_traits::queue_params_t & p ) {
90 p.lock_factory( prio_disp::queue_traits::simple_lock_factory() );
91 } ) );
92 \endcode
93 */
94 template< typename L >
95 disp_params_t &
tune_queue_params(L tunner)96 tune_queue_params( L tunner )
97 {
98 tunner( m_queue_params );
99 return *this;
100 }
101
102 //! Getter for queue parameters.
103 const queue_traits::queue_params_t &
queue_params() const104 queue_params() const noexcept
105 {
106 return m_queue_params;
107 }
108
109 private :
110 //! Queue parameters.
111 queue_traits::queue_params_t m_queue_params;
112 };
113
114 namespace impl
115 {
116
117 class dispatcher_handle_maker_t;
118
119 } /* namespace impl */
120
121 //
122 // dispatcher_handle_t
123 //
124
125 /*!
126 * \since
127 * v.5.6.0
128 *
129 * \brief A handle for %prio_one_thread::strictly_ordered dispatcher.
130 */
131 class [[nodiscard]] dispatcher_handle_t
132 {
133 friend class impl::dispatcher_handle_maker_t;
134
135 //! Binder for the dispatcher.
136 disp_binder_shptr_t m_binder;
137
dispatcher_handle_t(disp_binder_shptr_t binder)138 dispatcher_handle_t( disp_binder_shptr_t binder ) noexcept
139 : m_binder{ std::move(binder) }
140 {}
141
142 //! Is this handle empty?
143 bool
empty() const144 empty() const noexcept { return !m_binder; }
145
146 public :
147 dispatcher_handle_t() noexcept = default;
148
149 //! Get a binder for that dispatcher.
150 [[nodiscard]]
151 disp_binder_shptr_t
binder() const152 binder() const noexcept
153 {
154 return m_binder;
155 }
156
157 //! Is this handle empty?
operator bool() const158 operator bool() const noexcept { return empty(); }
159
160 //! Does this handle contain a reference to dispatcher?
161 bool
operator !() const162 operator!() const noexcept { return !empty(); }
163
164 //! Drop the content of handle.
165 void
reset()166 reset() noexcept { m_binder.reset(); }
167 };
168
169 //
170 // make_dispatcher
171 //
172 /*!
173 * \brief Create an instance of %strictly_ordered dispatcher.
174 *
175 * \par Usage sample
176 \code
177 auto common_thread_disp = so_5::disp::prio_one_thread::strictly_ordered::make_dispatcher(
178 env,
179 "request_processor",
180 so_5::disp::prio_one_thread::strictly_ordered::disp_params_t{}.tune_queue_params(
181 []( so_5::disp::prio_one_thread::strictly_ordered::queue_traits::queue_params_t & p ) {
182 p.lock_factory( so_5::disp::prio_one_thread::strictly_ordered::queue_traits::simple_lock_factory() );
183 } ) );
184 auto coop = env.make_coop(
185 // The main dispatcher for that coop will be
186 // this instance of strictly_ordered dispatcher.
187 common_thread_disp.binder() );
188 \endcode
189 *
190 * \since
191 * v.5.6.0
192 */
193 SO_5_FUNC dispatcher_handle_t
194 make_dispatcher(
195 //! SObjectizer Environment to work in.
196 environment_t & env,
197 //! Value for creating names of data sources for
198 //! run-time monitoring.
199 const std::string_view data_sources_name_base,
200 //! Parameters for the dispatcher.
201 disp_params_t params );
202
203 //
204 // make_dispatcher
205 //
206 /*!
207 * \brief Create an instance of %strictly_ordered dispatcher.
208 *
209 * \par Usage sample
210 \code
211 auto common_thread_disp = so_5::disp::prio_one_thread::strictly_ordered::make_dispatcher(
212 env,
213 "request_processor" );
214 auto coop = env.make_coop(
215 // The main dispatcher for that coop will be
216 // this instance of strictly_ordered dispatcher.
217 common_thread_disp.binder() );
218 \endcode
219 *
220 * \since
221 * v.5.6.0
222 */
223 inline dispatcher_handle_t
make_dispatcher(environment_t & env,const std::string_view data_sources_name_base)224 make_dispatcher(
225 //! SObjectizer Environment to work in.
226 environment_t & env,
227 //! Value for creating names of data sources for
228 //! run-time monitoring.
229 const std::string_view data_sources_name_base )
230 {
231 return make_dispatcher( env, data_sources_name_base, disp_params_t{} );
232 }
233
234 //
235 // make_dispatcher
236 //
237 /*!
238 * \brief Create an instance of %strictly_ordered dispatcher.
239 *
240 * \par Usage sample
241 \code
242 auto common_thread_disp = so_5::disp::prio_one_thread::strictly_ordered::make_dispatcher( env );
243
244 auto coop = env.make_coop(
245 // The main dispatcher for that coop will be
246 // private strictly_ordered dispatcher.
247 common_thread_disp.binder() );
248 \endcode
249 *
250 * \since
251 * v.5.6.0
252 */
253 inline dispatcher_handle_t
make_dispatcher(environment_t & env)254 make_dispatcher( environment_t & env )
255 {
256 return make_dispatcher( env, std::string_view{} );
257 }
258
259 } /* namespace strictly_ordered */
260
261 } /* namespace prio_one_thread */
262
263 } /* namespace disp */
264
265 } /* namespace so_5 */
266
267