SObjectizer 5.8
Loading...
Searching...
No Matches
layer_core.cpp
Go to the documentation of this file.
1/*
2 SObjectizer 5.
3*/
4
5#include <so_5/impl/layer_core.hpp>
6
7#include <so_5/details/rollback_on_exception.hpp>
8
9#include <algorithm>
10#include <iterator>
11
12namespace so_5
13{
14
15namespace impl
16{
17
18//
19// typed_layer_ref_t
20//
21
23 :
24 m_true_type( std::type_index( typeid( int ) ) )
25{
26}
27
29 const layer_map_t::value_type & v )
30 :
31 m_true_type( v.first ),
32 m_layer( v.second )
33{
34}
35
37 const std::type_index & type,
38 const layer_ref_t & layer )
39 :
40 m_true_type( type ),
41 m_layer( layer )
42{
43}
44
45bool
46typed_layer_ref_t::operator < ( const typed_layer_ref_t & tl ) const
47{
48 return m_true_type < tl.m_true_type;
49}
50
51//
52// layer_core_t
53//
54
56 environment_t & env,
57 layer_map_t && so_layers )
58 :
59 m_env( env ),
60 m_default_layers( so_layers.begin(), so_layers.end() )
61{
62 std::for_each( m_default_layers.begin(), m_default_layers.end(),
63 [this]( so_layer_list_t::value_type & item )
64 {
66 } );
67
68 // The content of so_layers is no more needed.
69 so_layers.clear();
70}
71
72//! Find layer in container.
73inline so_layer_list_t::const_iterator
75 const so_layer_list_t & layers,
76 const std::type_index & type )
77{
78 auto search_result = std::lower_bound( layers.begin(), layers.end(),
79 type,
80 []( const so_layer_list_t::value_type & a, const std::type_index & b )
81 {
82 return a.m_true_type < b;
83 } );
84 if( search_result != layers.end() && search_result->m_true_type == type )
85 return search_result;
86
87 return layers.end();
88}
89
90layer_t *
92 const std::type_index & type ) const
93{
94 // Try search within default layers first.
95 so_layer_list_t::const_iterator layer_it = search_for_layer(
97 type );
98
99 if( m_default_layers.end() != layer_it )
100 return layer_it->m_layer.get();
101
102 // Layer not found yet. Search extra layers.
103 std::lock_guard< std::mutex > lock( m_extra_layers_lock );
104
105 layer_it = search_for_layer(
107 type );
108
109 if( m_extra_layers.end() != layer_it )
110 return layer_it->m_layer.get();
111
112 return nullptr;
113}
114
115void
117{
118 so_layer_list_t::iterator
119 it = m_default_layers.begin(),
120 it_end = m_default_layers.end();
121
122 for(; it != it_end; ++it )
123 {
125 [&] { it->m_layer->start(); },
126 [&] {
127 std::for_each(
128 m_default_layers.begin(),
129 it,
130 []( typed_layer_ref_t & l ) { l.m_layer->shutdown(); } );
131
132 std::for_each(
133 m_default_layers.begin(),
134 it,
135 []( typed_layer_ref_t & l ) { l.m_layer->wait(); } );
136 } );
137 }
138}
139
140void
142{
143 // Shutdown and wait extra layers.
146
147 // Shutdown and wait default layers.
150}
151
152void
154 const std::type_index & type,
155 const layer_ref_t & layer )
156{
157 if( nullptr == layer.get() )
160 "trying to add nullptr extra layer" );
161
165 "trying to add extra layer that already exists in default list" );
166
167 std::lock_guard< std::mutex > lock( m_extra_layers_lock );
168
172 "trying to add extra layer that already exists in extra list" );
173
175
176 try
177 {
178 layer->start();
179 }
180 catch( const std::exception & x )
181 {
184 std::string( "layer raised an exception: " ) + x.what() );
185 }
186
187 try
188 {
189 typed_layer_ref_t typed_layer( type, layer );
190
191 m_extra_layers.insert(
192 std::lower_bound(
193 m_extra_layers.begin(),
194 m_extra_layers.end(),
195 typed_layer ),
196 typed_layer );
197 }
198 catch( const std::exception & x )
199 {
200 // Unable to store layer. Layer must be stopped...
201 layer->shutdown();
202 layer->wait();
203
204 // ...And error must be reported.
207 std::string( "unable to store pointer to layer, exception: " ) +
208 x.what() );
209 }
210}
211
212#if defined(__clang__)
213#pragma clang diagnostic push
214#pragma clang diagnostic ignored "-Wmissing-prototypes"
215#endif
216
217void
222void
224{
225 tl.m_layer->wait();
226}
227
228#if defined(__clang__)
229#pragma clang diagnostic pop
230#endif
231
232void
234{
235 std::for_each(
236 m_extra_layers.begin(),
237 m_extra_layers.end(),
239}
240
241void
243{
244 std::for_each(
245 m_extra_layers.begin(),
246 m_extra_layers.end(),
247 call_wait );
248
249 m_extra_layers.clear();
250}
251
252void
254{
255 std::for_each(
256 m_default_layers.begin(),
257 m_default_layers.end(),
259}
260
261void
263{
264 std::for_each(
265 m_default_layers.begin(),
266 m_default_layers.end(),
267 call_wait );
268
269}
270
271} /* namespace impl */
272
273} /* namespace so_5 */
SObjectizer Environment.
An utility class for working with layers.
std::mutex m_extra_layers_lock
Object lock for the extra layers data.
void shutdown_default_layers()
Shutdown default layers.
environment_t & m_env
SObjectizer Environment to work with.
layer_t * query_layer(const std::type_index &type) const
Get a layer.
void shutdown_extra_layers()
Shutdown extra layers.
so_layer_list_t m_default_layers
Default layers.
void add_extra_layer(const std::type_index &type, const layer_ref_t &layer)
Add an extra layer.
so_layer_list_t m_extra_layers
Extra layers.
void start()
Start all layers.
layer_core_t(environment_t &env, layer_map_t &&so_layers)
void wait_extra_layers()
Blocking wait for the complete shutdown of all extra layers.
void wait_default_layers()
Blocking wait for the complete shutdown of all default layers.
void finish()
Shutdown all layers and wait for full stop of them.
An interface of the additional SObjectizer Environment layer.
Definition so_layer.hpp:31
virtual void start()
Start hook.
Definition so_layer.cpp:13
virtual void shutdown()
Shutdown signal hook.
Definition so_layer.cpp:18
virtual void wait()
Waiting for the complete shutdown of a layer.
Definition so_layer.cpp:23
void bind_to_environment(environment_t *env)
Bind layer to the SObjectizer Environment.
Definition so_layer.cpp:41
#define SO_5_THROW_EXCEPTION(error_code, desc)
Definition exception.hpp:74
Some reusable and low-level classes/functions which can be used in public header files.
auto do_with_rollback_on_exception(Main_Action main_action, Rollback_Action rollback_action) -> decltype(main_action())
Helper function for do some action with rollback in the case of an exception.
Details of SObjectizer run-time implementations.
Definition agent.cpp:780
so_layer_list_t::const_iterator search_for_layer(const so_layer_list_t &layers, const std::type_index &type)
Find layer in container.
void call_shutdown(typed_layer_ref_t &tl)
void call_wait(typed_layer_ref_t &tl)
Private part of message limit implementation.
Definition agent.cpp:33
const int rc_unable_to_start_extra_layer
Layer initialization is failed.
Definition ret_code.hpp:164
const int rc_trying_to_add_extra_layer_that_already_exists_in_extra_list
The layer is already bound to the SObjectizer Environment as an extra layer.
Definition ret_code.hpp:161
const int rc_trying_to_add_extra_layer_that_already_exists_in_default_list
The layer is already bound to the SObjectizer Environment as a default layer.
Definition ret_code.hpp:158
const int rc_trying_to_add_nullptr_extra_layer
Unable to bind a layer by the null pointer to it.
Definition ret_code.hpp:155
A special wrapper to store a layer with its type.
std::type_index m_true_type
Layer type.
bool operator<(const typed_layer_ref_t &tl) const
typed_layer_ref_t(const std::type_index &type, const layer_ref_t &layer)
layer_ref_t m_layer
Layer itself.
typed_layer_ref_t(const layer_map_t::value_type &v)