2
3
5#include <so_5/coop.hpp>
7#include <so_5/impl/internal_env_iface.hpp>
8#include <so_5/impl/internal_agent_iface.hpp>
9#include <so_5/impl/agent_ptr_compare.hpp>
11#include <so_5/details/rollback_on_exception.hpp>
13#include <so_5/exception.hpp>
14#include <so_5/environment.hpp>
30 for(
auto & n : m_notificators )
43 for(
auto & n : m_notificators )
44 n( env, coop, reason );
64 coop.m_agent_array.clear();
68 for(
auto & d : coop.m_resource_deleters )
70 static_assert(
noexcept( d() ),
71 "resource deleter is expected to be noexcept" );
75 coop.m_resource_deleters.clear();
81 agent_ref_t agent_ref )
83 internal_agent_iface_t agent_iface{ *agent_ref };
86 agent_iface.set_disp_binder( coop.m_coop_disp_binder );
87 coop.m_agent_array.emplace_back( std::move(agent_ref) );
89 [&agent_iface]()
noexcept {
97 agent_ref_t agent_ref,
98 disp_binder_shptr_t disp_binder )
100 internal_agent_iface_t agent_iface{ *agent_ref };
103 agent_iface.set_disp_binder( std::move(disp_binder) );
104 coop.m_agent_array.emplace_back( std::move(agent_ref) );
106 [&agent_iface]()
noexcept {
114
115
116
117
118
119 template<
class C,
class N >
127 to = intrusive_ptr_t< C >(
new C() );
130 to->add( std::move(notificator) );
138 coop_reg_notificator_t notificator )
140 do_add_notificator_to(
141 coop.m_reg_notificators,
142 std::move(notificator) );
148 coop_dereg_notificator_t notificator )
150 do_add_notificator_to(
151 coop.m_dereg_notificators,
152 std::move(notificator) );
158 const coop_t & coop )
noexcept
162 const auto parent = so_5::low_level_api::to_shptr_noexcept(
165 return parent->exception_reaction();
179 if( 0 == --coop.m_reference_count )
194 const auto should_finalize = [&] {
195 std::lock_guard< std::mutex > lock{ coop.m_lock };
209 if( should_finalize() )
212 .ready_to_deregister_notify( coop.shared_from_this() );
232 so_5::
details::do_with_rollback_on_exception( [
this] {
237 std::lock_guard< std::mutex > lock{ m_coop.m_lock };
241 details::invoke_noexcept_code( [&] {
274 std::begin(m_coop.m_agent_array),
275 std::end(m_coop.m_agent_array),
276 [](
const auto & a,
const auto & b )
noexcept {
277 return special_agent_ptr_compare( *a, *b );
284 for(
const auto & agent_ref : m_coop.m_agent_array )
286 internal_agent_iface_t{ *agent_ref }.bind_to_coop( m_coop );
295 coop_t::agent_array_t::iterator it;
298 for( it = m_coop.m_agent_array.begin();
299 it != m_coop.m_agent_array.end();
302 agent_t & agent = **it;
303 internal_agent_iface_t agent_iface{ agent };
304 agent_iface.query_disp_binder()
305 .preallocate_resources( agent );
308 catch(
const std::exception & x )
311 for(
auto it2 = m_coop.m_agent_array.begin();
315 agent_t & agent = **it2;
316 internal_agent_iface_t agent_iface{ agent };
317 agent_iface.query_disp_binder()
318 .undo_preallocation( agent );
322 rc_agent_to_disp_binding_failed,
324 "an exception during the first stage of "
325 "binding agent to the dispatcher, exception: " }
335 for(
const auto & agent_ref : m_coop.m_agent_array )
336 internal_agent_iface_t{ *agent_ref }
337 .initiate_agent_definition();
343 catch(
const std::exception & ex )
346 rc_coop_define_agent_failed,
352 rc_coop_define_agent_failed,
353 "exception of unknown type has been thrown in "
354 "so_define_agent()" );
361 so_5::low_level_api::to_shptr(m_coop.m_parent)->add_child(
362 m_coop.shared_from_this() );
368 for(
const auto & agent_ref : m_coop.m_agent_array )
370 internal_agent_iface_t agent_iface{ *agent_ref };
371 agent_iface.query_disp_binder().bind( *agent_ref );
378 for(
const auto & agent_ref : m_coop.m_agent_array )
380 internal_agent_iface_t agent_iface{ *agent_ref };
381 agent_iface.query_disp_binder()
382 .undo_preallocation( *agent_ref );
429 std::lock_guard< std::mutex > lock{ m_coop.m_lock };
450 for(
const auto & agent_ref : m_coop.m_agent_array )
452 internal_agent_iface_t{ *agent_ref }.shutdown_agent();
505 for(
const auto & agent_ref : coop.m_agent_array )
507 agent_t & agent = *agent_ref;
508 internal_agent_iface_t agent_iface{ agent };
509 agent_iface.query_disp_binder().unbind( agent );
517 so_5::low_level_api::to_shptr(coop.m_parent)->remove_child( coop );
530 so_5::
details::do_with_rollback_on_exception( [&] {
533 std::lock_guard< std::mutex > lock{ parent.m_lock };
537 if( coop_t::registration_status_t::coop_registered !=
538 parent.m_registration_status )
540 rc_coop_is_not_in_registered_state,
541 "add_child() can be processed only when coop "
545 if( parent.m_first_child )
546 parent.m_first_child->m_prev_sibling = child;
548 child->m_next_sibling = std::move(parent.m_first_child);
550 parent.m_first_child = std::move(child);
567 std::lock_guard< std::mutex > lock{ parent.m_lock };
569 if( parent.m_first_child.get() == &child )
573 parent.m_first_child = child.m_next_sibling;
574 if( parent.m_first_child )
575 parent.m_first_child->m_prev_sibling.reset();
579 child.m_prev_sibling->m_next_sibling = child.m_next_sibling;
580 if( child.m_next_sibling )
581 child.m_next_sibling->m_prev_sibling = child.m_prev_sibling;
Container for cooperation deregistration notificators.
void call_all(environment_t &env, const coop_handle_t &coop, const coop_dereg_reason_t &reason) const noexcept
Call all notificators.
It's a kind of strong typedef for coop's deregistration reason.
Type of smart handle for a cooperation.
Container for cooperation registration notificators.
void call_all(environment_t &env, const coop_handle_t &coop) const noexcept
Call all notificators.
environment_t & environment() const noexcept
Access to SO Environment for which cooperation is bound.
registration_status_t m_registration_status
The registration status of cooperation.
void decrement_usage_count() noexcept
Decrement usage count for the coop.
void deregister(int reason) noexcept
Deregister the cooperation with the specified reason.
exception_reaction_t m_exception_reaction
A reaction to non-handled exception.
registration_status_t
Registration status.
@ deregistration_in_final_stage
Deregistration of the coop is in the final stage.
@ coop_registered
Cooperation is registered.
@ coop_deregistering
Cooperation is in deregistration process.
coop_dereg_reason_t m_dereg_reason
Deregistration reason.
void increment_usage_count() noexcept
Increment usage count for the coop.
exception_reaction_t exception_reaction() const noexcept
An exception reaction for the whole SO Environment.
The base class for all SObjectizer exceptions.
An internal class with real implementation of coop's logic.
static void destroy_content(coop_t &coop) noexcept
Perform all necessary cleanup actions for coop.
static void do_final_deregistration_actions(coop_t &coop)
Perform final deregistration actions for an coop.
static exception_reaction_t exception_reaction(const coop_t &coop) noexcept
Get exception reaction for coop.
static void do_remove_child(coop_t &parent, coop_t &child) noexcept
Perform removement of a child coop.
static void do_decrement_reference_count(coop_t &coop) noexcept
Do decrement reference count for a coop.
static void do_deregistration_specific_actions(coop_t &coop, coop_dereg_reason_t reason) noexcept
Perform actions related to the deregistration of coop.
static void do_registration_specific_actions(coop_t &coop)
Perform actions related to the registration of coop.
static void do_add_agent(coop_t &coop, agent_ref_t agent_ref)
Add agent to cooperation.
void drop_disp_binder() noexcept
Helper method that drops pointer to disp_binder.
A helper class for accessing the functionality of environment-class which is specific for SObjectizer...
Template class for smart reference wrapper on the atomic_refcounted_t.
#define SO_5_THROW_EXCEPTION(error_code, desc)
Enumeration of cooperation deregistration reasons.
const int parent_deregistration
Deregistration because parent cooperation deregistration.
Some reusable and low-level classes/functions which can be used in public header files.
void do_add_notificator_to(intrusive_ptr_t< C > &to, N notificator)
Helper function for notificator addition.
Details of SObjectizer run-time implementations.
Private part of message limit implementation.
exception_reaction_t
A reaction of SObjectizer to an exception from agent event.
@ inherit_exception_reaction
Exception reaction should be inherited from SO Environment.