SObjectizer  5.8
Loading...
Searching...
No Matches
prio_one_thread/strictly_ordered/pub.cpp
Go to the documentation of this file.
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 v.5.5.8
11 */
12
13#include <so_5/disp/prio_one_thread/strictly_ordered/pub.hpp>
14
15#include <so_5/disp/prio_one_thread/strictly_ordered/impl/demand_queue.hpp>
16#include <so_5/disp/prio_one_thread/reuse/work_thread.hpp>
17
18#include <so_5/disp/reuse/actual_work_thread_factory_to_use.hpp>
19#include <so_5/disp/reuse/data_source_prefix_helpers.hpp>
20#include <so_5/disp/reuse/make_actual_dispatcher.hpp>
21
22#include <so_5/stats/repository.hpp>
23#include <so_5/stats/messages.hpp>
24#include <so_5/stats/std_names.hpp>
25
26#include <so_5/send_functions.hpp>
27
28namespace so_5 {
29
30namespace disp {
31
32namespace prio_one_thread {
33
35
36namespace impl {
37
38namespace stats = so_5::stats;
39
40namespace {
41
42void
44 const so_5::mbox_t &,
45 const stats::prefix_t &,
47 demand_queue_t > & )
48 {
49 /* Nothing to do */
50 }
51
52void
54 const so_5::mbox_t & mbox,
55 const stats::prefix_t & prefix,
56 so_5::disp::prio_one_thread::reuse::work_thread_with_activity_tracking_t<
57 demand_queue_t > & wt )
58 {
59 so_5::send< stats::messages::work_thread_activity >(
60 mbox,
61 prefix,
62 stats::suffixes::work_thread_activity(),
63 wt.thread_id(),
64 wt.take_activity_stats() );
65 }
66
67} /* namespace anonymous */
68
69//
70// dispatcher_template_t
71//
72/*!
73 * \brief An implementation of dispatcher with one working
74 * thread and support of demand priorities in form of template class.
75 *
76 * \since v.5.5.8, v.5.5.18, v.5.6.0
77 */
78template< typename Work_Thread >
79class dispatcher_template_t final : public disp_binder_t
80 {
81 friend class disp_data_source_t;
82
83 public:
86 const std::string_view name_base,
87 disp_params_t params )
88 : m_demand_queue{ params.queue_params().lock_factory()() }
89 , m_work_thread{
90 so_5::disp::reuse::acquire_work_thread( params, env.get() ),
91 m_demand_queue
92 }
93 , m_data_source{
94 outliving_mutable(env.get().stats_repository()),
95 name_base,
96 outliving_mutable(*this)
97 }
98 {
99 m_work_thread.start();
100 }
101
102 ~dispatcher_template_t() noexcept override
103 {
104 m_demand_queue.stop();
105 m_work_thread.join();
106 }
107
108 void
110 agent_t & /*agent*/ ) override
111 {
112 // Nothing to do.
113 }
114
115 void
117 agent_t & /*agent*/ ) noexcept override
118 {
119 // Nothing to do.
120 }
121
122 void
124 agent_t & agent ) noexcept override
125 {
126 const auto priority = agent.so_priority();
127
128 agent.so_bind_to_dispatcher(
129 m_demand_queue.event_queue_by_priority( priority ) );
130
131 m_demand_queue.agent_bound( priority );
132 }
133
134 void
136 agent_t & agent ) noexcept override
137 {
138 const auto priority = agent.so_priority();
139
140 m_demand_queue.agent_unbound( priority );
141 }
142
143 private:
144
145 /*!
146 * \brief Data source for run-time monitoring of whole dispatcher.
147 *
148 * \since v.5.5.8
149 */
150 class disp_data_source_t : public stats::source_t
151 {
152 //! Dispatcher to work with.
153 outliving_reference_t< dispatcher_template_t > m_dispatcher;
154
155 //! Basic prefix for data sources.
157
158 public :
160 const std::string_view name_base,
161 outliving_reference_t< dispatcher_template_t > disp )
162 : m_dispatcher{ disp }
164 "pot-so",
165 name_base,
166 &(disp.get()) )
167 }
168 {}
169
170 void
171 distribute( const mbox_t & mbox ) override
172 {
173 auto & disp = m_dispatcher.get();
174
176
178 [&]( const demand_queue_t::queue_stats_t & stat ) {
180 mbox,
184
186 } );
187
189 mbox,
192 agents_count );
193
195 mbox,
198 }
199
200 private:
201 void
203 const mbox_t & mbox,
204 priority_t priority,
205 std::size_t agents_count,
206 std::size_t demands_count )
207 {
209 ss << m_base_prefix.c_str() << "/p" << to_size_t(priority);
210
211 const stats::prefix_t prefix{ ss.str() };
212
214 mbox,
215 prefix,
217 agents_count );
218
220 mbox,
221 prefix,
224 }
225 };
226
227 //! Demand queue for the dispatcher.
229
230 //! Working thread for the dispatcher.
231 Work_Thread m_work_thread;
232
233 //! Data source for run-time monitoring.
236 };
237
238//
239// dispatcher_handle_maker_t
240//
242 {
243 public :
245 make( disp_binder_shptr_t binder ) noexcept
246 {
247 return { std::move( binder ) };
248 }
249 };
250
251} /* namespace impl */
252
253//
254// make_dispatcher
255//
258 environment_t & env,
259 const std::string_view data_sources_name_base,
260 disp_params_t params )
261 {
262 using namespace so_5::disp::reuse;
263 using namespace so_5::disp::prio_one_thread::reuse;
264
265 using dispatcher_no_activity_tracking_t =
266 impl::dispatcher_template_t<
267 work_thread_no_activity_tracking_t< impl::demand_queue_t > >;
268
269 using dispatcher_with_activity_tracking_t =
270 impl::dispatcher_template_t<
271 work_thread_with_activity_tracking_t< impl::demand_queue_t > >;
272
273 disp_binder_shptr_t binder = so_5::disp::reuse::make_actual_dispatcher<
274 disp_binder_t,
275 dispatcher_no_activity_tracking_t,
276 dispatcher_with_activity_tracking_t >(
277 outliving_mutable(env),
278 data_sources_name_base,
279 std::move(params) );
280
281 return impl::dispatcher_handle_maker_t::make( std::move(binder) );
282 }
283
284} /* namespace strictly_ordered */
285
286} /* namespace prio_one_thread */
287
288} /* namespace disp */
289
290} /* namespace so_5 */
A base class for agents.
Definition agent.hpp:673
void distribute_value_for_priority(const mbox_t &mbox, priority_t priority, std::size_t agents_count, std::size_t demands_count)
void distribute(const mbox_t &mbox) override
Send appropriate notification about the current value.
disp_data_source_t(const std::string_view name_base, outliving_reference_t< dispatcher_template_t > disp)
void unbind(agent_t &agent) noexcept override
Unbind agent from dispatcher.
dispatcher_template_t(outliving_reference_t< environment_t > env, const std::string_view name_base, disp_params_t params)
void preallocate_resources(agent_t &) override
Allocate resources in dispatcher for new agent.
stats::auto_registered_source_holder_t< disp_data_source_t > m_data_source
Data source for run-time monitoring.
Interface for dispatcher binders.
SObjectizer Environment.
Helper class for indication of long-lived reference via its type.
Definition outliving.hpp:98
A holder for data-souce that should be automatically registered and deregistered in registry.
A type for storing prefix of data_source name.
Definition prefix.hpp:32
An interface of data source.
#define SO_5_FUNC
Definition declspec.hpp:48
void send_thread_activity_stats(const so_5::mbox_t &, const stats::prefix_t &, so_5::disp::prio_one_thread::reuse::work_thread_no_activity_tracking_t< demand_queue_t > &)
Reusable code for dispatchers with one working thread for events of all priorities.
Implementation details for dispatcher which handles prioritized events in strict order.
Dispatcher which handles events in strict order (from highest priority to lowest).
SO_5_FUNC dispatcher_handle_t make_dispatcher(environment_t &env, const std::string_view data_sources_name_base, disp_params_t params)
Create an instance of strictly_ordered dispatcher.
Dispatcher with one working thread for events of all priorities.
Reusable components for dispatchers.
Event dispatchers.
All stuff related to run-time monitoring and statistics.
Private part of message limit implementation.
Definition agent.cpp:33
priority_t
Definition of supported priorities.
Definition priority.hpp:28