SObjectizer  5.5
Classes | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions | Friends | List of all members
so_5::coop_t Class Reference

Agent cooperation. More...

#include <coop.hpp>

Inheritance diagram for so_5::coop_t:
so_5::impl::coop_repository_basis_t::root_coop_t

Classes

struct  agent_with_disp_binder_t
 Information about agent and its dispatcher binding. More...
 
struct  resource_deleter_t
 Type of user resource deleter. More...
 

Public Member Functions

virtual ~coop_t ()
 
SO_5_NODISCARD coop_handle_t handle () noexcept
 Get handle for this coop. More...
 
SO_5_NODISCARD coop_id_t id () const noexcept
 Get the ID of coop. More...
 
SO_5_NODISCARD environment_tenvironment () const noexcept
 Access to SO Environment for which cooperation is bound. More...
 
template<class Agent >
Agent * add_agent (std::unique_ptr< Agent > agent)
 Add agent to cooperation. More...
 
template<class Agent >
Agent * add_agent (std::unique_ptr< Agent > agent, disp_binder_shptr_t disp_binder)
 Add agent to the cooperation with the dispatcher binding. More...
 
template<class Agent , typename... Args>
Agent * make_agent (Args &&... args)
 Helper method for simplification of agents creation. More...
 
template<class Agent , typename... Args>
Agent * make_agent_with_binder (so_5::disp_binder_shptr_t binder, Args &&... args)
 Helper method for simplification of agents creation and binding to the specified dispatcher. More...
 
std::size_t query_agent_count () const noexcept
 Get agent count in the cooperation. More...
 
std::size_t size () const noexcept
 Get agent count in the cooperation. More...
 
std::size_t capacity () const noexcept
 Get the capacity of vector for holding agents list. More...
 
void reserve (std::size_t v)
 Reserve a space for vector for holding agents list. More...
 
void deregister (int reason) noexcept
 Deregister the cooperation with the specified reason. More...
 
void deregister_normally () noexcept
 Deregistr the cooperation normally. More...
 
Method for working with notificators.
template<typename Lambda >
void add_reg_notificator (Lambda &&notificator)
 Add notificator about cooperation registration event. More...
 
template<typename Lambda >
void add_dereg_notificator (Lambda &&notificator)
 Add notificator about cooperation deregistration event. More...
 
Method for working with user resources.
template<class T >
T * take_under_control (std::unique_ptr< T > resource)
 Take a user resouce under cooperation control. More...
 
Exception reaction methods.
void set_exception_reaction (exception_reaction_t value) noexcept
 Set exception reaction for that cooperation. More...
 
SO_5_NODISCARD exception_reaction_t exception_reaction () const noexcept
 Get the current exception rection flag for that cooperation. More...
 

Protected Types

enum  registration_status_t { registration_status_t::coop_not_registered, registration_status_t::coop_registered, registration_status_t::coop_deregistering, registration_status_t::deregistration_in_final_stage }
 Registration status. More...
 
using agent_array_t = std::vector< agent_with_disp_binder_t >
 Typedef for the agent information container. More...
 
using resource_deleter_vector_t = std::vector< resource_deleter_t >
 Type of container for user resource deleters. More...
 

Protected Member Functions

 coop_t (coop_id_t id, coop_handle_t parent, disp_binder_shptr_t coop_disp_binder, outliving_reference_t< environment_t > env)
 Constructor. More...
 
void increment_usage_count () noexcept
 Increment usage count for the coop. More...
 
void decrement_usage_count () noexcept
 Decrement usage count for the coop. More...
 
void add_child (coop_shptr_t child)
 Add a new child to the parent coop. More...
 
void remove_child (coop_t &child)
 Remove a child from the parent coop. More...
 
template<typename Lambda >
void for_each_child (Lambda &&lambda) const
 A helper method for doing some actions with children coops. More...
 

Protected Attributes

const coop_id_t m_id
 Cooperation ID. More...
 
coop_handle_t m_parent
 Parent coop. More...
 
disp_binder_shptr_t m_coop_disp_binder
 Default agent to the dispatcher binder. More...
 
agent_array_t m_agent_array
 Cooperation agents. More...
 
outliving_reference_t< environment_tm_env
 SObjectizer Environment for which cooperation is created. More...
 
atomic_counter_t m_reference_count { 0l }
 Count for entities. More...
 
coop_reg_notificators_container_ref_t m_reg_notificators
 Notificators for registration event. More...
 
coop_dereg_notificators_container_ref_t m_dereg_notificators
 Notificators for deregistration event. More...
 
std::mutex m_lock
 A lock for synchonization of some operations on coop. More...
 
registration_status_t m_registration_status
 The registration status of cooperation. More...
 
resource_deleter_vector_t m_resource_deleters
 Container of user resource deleters. More...
 
coop_dereg_reason_t m_dereg_reason
 Deregistration reason. More...
 
exception_reaction_t m_exception_reaction
 A reaction to non-handled exception. More...
 
coop_shptr_t m_first_child
 The head of list of children coops. More...
 
coop_shptr_t m_prev_sibling
 The previous coop in sibling's chain. More...
 
coop_shptr_t m_next_sibling
 The next coop in sibling's chain. More...
 

Private Member Functions

 coop_t (const coop_t &)=delete
 
coop_toperator= (const coop_t &)=delete
 
 coop_t (coop_t &&)=delete
 
coop_toperator= (coop_t &&)=delete
 

Friends

class agent_t
 
class impl::coop_private_iface_t
 
class impl::coop_impl_t
 
class impl::coop_impl_t::registration_performer_t
 
class impl::coop_impl_t::deregistration_performer_t
 

Detailed Description

Agent cooperation.

The main purpose of the cooperation is the introducing of several agents into SObjectizer as a single unit. A cooperation should be registered.

For the cooperation to be successfuly registered all of its agents must successfuly pass registration steps (so-define, bind to the dispatcher). If at least one agent out of this cooperation fails to pass any of mentioned steps, the cooperation will not be registered and all of agents will run procedures opposite to registration steps (unbind from the dispatcher, so-undefine) which had been successfuly taken for the particulary agent in the reverse order.

Agents are added to the cooperation by the add_agent() method.

After addition to the cooperation the cooperation takes care about the agent lifetime.

Examples:
so_5/adv_thread_pool_fifo/main.cpp, so_5/blinking_led/main.cpp, so_5/chameneos_prealloc_msgs/main.cpp, so_5/chameneos_simple/main.cpp, so_5/chstate_msg_tracing/main.cpp, so_5/coop_notification/main.cpp, so_5/coop_user_resources/main.cpp, so_5/disp/main.cpp, so_5/dispatcher_for_children/main.cpp, so_5/dispatcher_restarts/main.cpp, so_5/hello_all/main.cpp, so_5/hello_world_simple_not_mtsafe/main.cpp, so_5/intercom_statechart/main.cpp, so_5/machine_control/main.cpp, so_5/make_pipeline/main.cpp, so_5/many_timers/main.cpp, so_5/modify_resend_as_immutable/main.cpp, so_5/mutable_msg_agents/main.cpp, so_5/news_board/main.cpp, so_5/nohandler_msg_tracing/main.cpp, so_5/parent_coop/main.cpp, so_5/ping_pong/main.cpp, so_5/ping_pong_minimal/main.cpp, so_5/prio_work_stealing/main.cpp, so_5/producer_consumer_mchain/main.cpp, so_5/queue_size_stats/main.cpp, so_5/redirect_and_transform/main.cpp, so_5/selective_msg_tracing/main.cpp, so_5/simple_message_deadline/main.cpp, so_5/state_deep_history/main.cpp, so_5/stop_guard/main.cpp, and so_5/wrapped_env_demo_2/main.cpp.

Member Typedef Documentation

◆ agent_array_t

using so_5::coop_t::agent_array_t = std::vector< agent_with_disp_binder_t >
protected

Typedef for the agent information container.

◆ resource_deleter_vector_t

Type of container for user resource deleters.

Since
v.5.2.3

Member Enumeration Documentation

◆ registration_status_t

Registration status.

Since
v.5.2.3
Enumerator
coop_not_registered 

Cooperation is not registered yet.

coop_registered 

Cooperation is registered.

Reference count for cooperation in that state should be greater than zero.

coop_deregistering 

Cooperation is in deregistration process.

Reference count for cooperation in that state should be zero.

deregistration_in_final_stage 

Deregistration of the coop is in the final stage.

Constructor & Destructor Documentation

◆ coop_t() [1/3]

so_5::coop_t::coop_t ( const coop_t )
privatedelete

◆ coop_t() [2/3]

so_5::coop_t::coop_t ( coop_t &&  )
privatedelete

◆ coop_t() [3/3]

so_5::coop_t::coop_t ( coop_id_t  id,
coop_handle_t  parent,
disp_binder_shptr_t  coop_disp_binder,
outliving_reference_t< environment_t env 
)
inlineprotected

Constructor.

Parameters
idCooperation ID.
parentParent coop.
coop_disp_binderDefault dispatcher binding.
envSObjectizer Environment.

◆ ~coop_t()

virtual so_5::coop_t::~coop_t ( )
inlinevirtual

Member Function Documentation

◆ add_agent() [1/2]

template<class Agent >
Agent* so_5::coop_t::add_agent ( std::unique_ptr< Agent >  agent)
inline

Add agent to cooperation.

Cooperation takes care about agent lifetime.

Default dispatcher binding is used for the agent.

Parameters
agentAgent.

◆ add_agent() [2/2]

template<class Agent >
Agent* so_5::coop_t::add_agent ( std::unique_ptr< Agent >  agent,
disp_binder_shptr_t  disp_binder 
)
inline

Add agent to the cooperation with the dispatcher binding.

Instead of the default dispatcher binding the disp_binder is used for this agent during the cooperation registration.

Parameters
agentAgent.
disp_binderAgent to dispatcher binder.

◆ add_child()

void so_5::coop_t::add_child ( coop_shptr_t  child)
inlineprotected

Add a new child to the parent coop.

This method is called by child coop.

Note
This method locks the parent coop object. But under that lock fields m_prev_sibling and m_next_sibling of the child coop are modified.
Since
v.5.6.0
Parameters
childChild coop to be added.

◆ add_dereg_notificator()

template<typename Lambda >
void so_5::coop_t::add_dereg_notificator ( Lambda &&  notificator)
inline

Add notificator about cooperation deregistration event.

Since
v.5.2.3
Attention
Since v.5.6.0 dereg_notificator should be a noexcept function or functor. Because of that a check in performed during compile time. An attempt to pass non-noexcept function or functor to add_dereg_notificator will lead to compilation error.
Examples:
so_5/coop_notification/main.cpp, and so_5/dispatcher_restarts/main.cpp.

◆ add_reg_notificator()

template<typename Lambda >
void so_5::coop_t::add_reg_notificator ( Lambda &&  notificator)
inline

Add notificator about cooperation registration event.

Since
v.5.2.3
Attention
Since v.5.6.0 reg_notificator should be a noexcept function or functor. Because of that a check in performed during compile time. An attempt to pass non-noexcept function or functor to add_reg_notificator will lead to compilation error.
Examples:
so_5/coop_notification/main.cpp.

◆ capacity()

std::size_t so_5::coop_t::capacity ( ) const
inlinenoexcept

Get the capacity of vector for holding agents list.

Since
v.5.5.16

◆ decrement_usage_count()

void so_5::coop_t::decrement_usage_count ( )
inlineprotectednoexcept

Decrement usage count for the coop.

Note that is usage count is become 0 then final deregistration actions will be initiated.

Cooperation deregistration is a long process. All agents process events out of their queues. When an agent detects that no more events in its queue it informs the cooperation about this.

When cooperation detects that all agents have finished their work it initiates the agent's destruction.

Since v.5.2.3 this method used not only for agents of cooperation but and for children cooperations. Because final step of cooperation deregistration could be initiated only when all children cooperations are deregistered and destroyed.

Note
This method is marked as noexcept because there is no way to recover if any exception is raised here.

◆ deregister()

void so_5::coop_t::deregister ( int  reason)
inlinenoexcept

Deregister the cooperation with the specified reason.

Since
v.5.5.8
Usage example:
coop_t & coop = ...;
coop.deregister( so_4::dereg_reason::user_defined_reason + 100 );
Note
This method is marked as noexcept because there is no way to recover if any exception is raised here.
Parameters
reasonReason of cooperation deregistration.

◆ deregister_normally()

void so_5::coop_t::deregister_normally ( )
inlinenoexcept

Deregistr the cooperation normally.

Since
v.5.5.8

This method is just a shorthand for:

Note
This method is marked as noexcept because there is no way to recover if any exception is raised here.

◆ environment()

SO_5_NODISCARD environment_t& so_5::coop_t::environment ( ) const
inlinenoexcept

Access to SO Environment for which cooperation is bound.

Since
v.5.3.0
Examples:
so_5/disp/main.cpp, so_5/machine_control/main.cpp, so_5/prio_work_stealing/main.cpp, and so_5/producer_consumer_mchain/main.cpp.

◆ exception_reaction()

SO_5_NODISCARD exception_reaction_t so_5::coop_t::exception_reaction ( ) const
inlinenoexcept

Get the current exception rection flag for that cooperation.

Since
v.5.3.0

It uses the following logic:

  • if own's exception_reaction flag value differs from inherit_exception_reaction value than own's exception_reaction flag value returned;
  • otherwise if there is a parent cooperation than parent coop's exception_reaction value returned;
  • otherwise SO Environment's exception_reaction is returned.

◆ for_each_child()

template<typename Lambda >
void so_5::coop_t::for_each_child ( Lambda &&  lambda) const
inlineprotected

A helper method for doing some actions with children coops.

This method is intended to be used in derived classes where an access to m_first_child, m_prev_sibling and m_next_sibling from another coop object will be prohibited.

Since
v.5.6.0

◆ handle()

SO_5_NODISCARD coop_handle_t so_5::coop_t::handle ( )
inlinenoexcept

Get handle for this coop.

Since
v.5.6.0
Examples:
so_5/coop_notification/main.cpp.

◆ id()

SO_5_NODISCARD coop_id_t so_5::coop_t::id ( ) const
inlinenoexcept

Get the ID of coop.

Since
v.5.6.0

◆ increment_usage_count()

void so_5::coop_t::increment_usage_count ( )
inlineprotectednoexcept

Increment usage count for the coop.

In v.5.2.3 the counter m_reference_count is used to reflect count of references to the cooperation. There are the following entities who can refer to cooperation:

  • agents from that cooperation. When cooperation is successfully registered the counter is incremented by count of agents. During cooperation deregistration agents finish their work and each agent decrement cooperation usage counter;
  • children cooperations. Each child cooperation increments reference counter on its registration and decrements counter on its deregistration;
  • cooperation registration routine. It increment reference counter to prevent cooperation deregistration before the end of registration process. It is possible if cooperation do its work very quickly and initiates deregistration. When cooperation has coop_notificators its registration process may be longer then cooperation working time. And cooperation could be deregistered and even destroyed before return from registration routine. To prevent this cooperation registration routine increments cooperation usage counter and the begin of process and decrement it when registration process finished.

◆ make_agent()

template<class Agent , typename... Args>
Agent* so_5::coop_t::make_agent ( Args &&...  args)
inline

Helper method for simplification of agents creation.

Since
v.5.5.4
Note
Creates an instance of agent of type Agent and adds it to the cooperation.
Returns
pointer to the new agent.
Template Parameters
Agenttype of agent to be created.
Argstype of parameters list for agent constructor.
Usage sample:
auto coop = env.make_coop();
// For the case of constructor like my_agent(environmen_t&).
coop->make_agent< my_agent >();
// For the case of constructor like your_agent(environment_t&, std::string).
auto ya = coop->make_agent< your_agent >( "hello" );
// For the case of constructor like thier_agent(environment_t&, std::string, mbox_t).
coop->make_agent< their_agent >( "bye", ya->so_direct_mbox() );
Examples:
so_5/adv_thread_pool_fifo/main.cpp, so_5/blinking_led/main.cpp, so_5/chameneos_prealloc_msgs/main.cpp, so_5/chameneos_simple/main.cpp, so_5/chstate_msg_tracing/main.cpp, so_5/coop_notification/main.cpp, so_5/coop_user_resources/main.cpp, so_5/disp/main.cpp, so_5/dispatcher_hello/main.cpp, so_5/dispatcher_restarts/main.cpp, so_5/hardwork_imit/main.cpp, so_5/hello_all/main.cpp, so_5/hello_world_simple_not_mtsafe/main.cpp, so_5/intercom_statechart/main.cpp, so_5/machine_control/main.cpp, so_5/many_timers/main.cpp, so_5/modify_resend_as_immutable/main.cpp, so_5/mutable_msg_agents/main.cpp, so_5/news_board/main.cpp, so_5/nohandler_msg_tracing/main.cpp, so_5/parent_coop/main.cpp, so_5/ping_pong_minimal/main.cpp, so_5/prio_work_stealing/main.cpp, so_5/queue_size_stats/main.cpp, so_5/redirect_and_transform/main.cpp, so_5/selective_msg_tracing/main.cpp, so_5/simple_message_deadline/main.cpp, so_5/state_deep_history/main.cpp, so_5/stop_guard/main.cpp, and so_5/wrapped_env_demo_2/main.cpp.

◆ make_agent_with_binder()

template<class Agent , typename... Args>
Agent* so_5::coop_t::make_agent_with_binder ( so_5::disp_binder_shptr_t  binder,
Args &&...  args 
)
inline

Helper method for simplification of agents creation and binding to the specified dispatcher.

Since
v.5.5.4
Note
Creates an instance of agent of type Agent and adds it to the cooperation with the specified binder.
Returns
pointer to the new agent.
Template Parameters
Agenttype of agent to be created.
Argstype of parameters list for agent constructor.
Usage sample:
auto coop = env.make_coop();
// For the case of constructor like my_agent(environmen_t&).
coop->make_agent_with_binder< my_agent >( disp.binder() );
// For the case of constructor like your_agent(environment_t&, std::string).
auto ya = coop->make_agent_with_binder< your_agent >( disp.binder(), "hello" );
// For the case of constructor like thier_agent(environment_t&, std::string, mbox_t).
coop->make_agent_with_binder< their_agent >( disp.binder(), "bye", ya->so_direct_mbox() );
Parameters
binderA dispatcher binder for the new agent.
argsArguments to be passed to the agent's constructor.
Examples:
so_5/disp/main.cpp, so_5/machine_control/main.cpp, so_5/prio_work_stealing/main.cpp, so_5/producer_consumer_mchain/main.cpp, so_5/queue_size_stats/main.cpp, and so_5/redirect_and_transform/main.cpp.

◆ operator=() [1/2]

coop_t& so_5::coop_t::operator= ( const coop_t )
privatedelete

◆ operator=() [2/2]

coop_t& so_5::coop_t::operator= ( coop_t &&  )
privatedelete

◆ query_agent_count()

std::size_t so_5::coop_t::query_agent_count ( ) const
inlinenoexcept

Get agent count in the cooperation.

Since
v.5.5.4

◆ remove_child()

void so_5::coop_t::remove_child ( coop_t child)
inlineprotected

Remove a child from the parent coop.

This method is called by child coop.

Note
This method locks the parent coop object. But under that lock fields m_prev_sibling and m_next_sibling of the child coop are modified.
In contradiction to add_child() this method receives a reference to child coop. This allows to avoid construction of temporary shared_ptr object.
Since
v.5.6.0
Parameters
childChild coop to be removed.

◆ reserve()

void so_5::coop_t::reserve ( std::size_t  v)
inline

Reserve a space for vector for holding agents list.

Since
v.5.5.16

This method can help avoid reallocations of agents list during filling the coop:

env.introduce_coop( []( so_5::coop_t & coop ) {
coop.reserve( agents_count );
for( size_t i = 0; i != agents_count; ++i )
coop.make_agent< some_type >( some_args );
} );

◆ set_exception_reaction()

void so_5::coop_t::set_exception_reaction ( exception_reaction_t  value)
inlinenoexcept

Set exception reaction for that cooperation.

Since
v.5.3.0

This value will be used by agents and children cooperation if they use inherit_exception_reaction value.

Examples:
so_5/coop_notification/main.cpp.

◆ size()

std::size_t so_5::coop_t::size ( ) const
inlinenoexcept

Get agent count in the cooperation.

Since
v.5.5.16
Note
Just an alias for query_agent_count().

◆ take_under_control()

template<class T >
T* so_5::coop_t::take_under_control ( std::unique_ptr< T >  resource)
inline

Take a user resouce under cooperation control.

Since
v.5.2.3
Examples:
so_5/coop_user_resources/main.cpp, so_5/machine_control/main.cpp, so_5/news_board/main.cpp, and so_5/prio_work_stealing/main.cpp.

Friends And Related Function Documentation

◆ agent_t

friend class agent_t
friend

◆ impl::coop_impl_t

friend class impl::coop_impl_t
friend

◆ impl::coop_impl_t::deregistration_performer_t

◆ impl::coop_impl_t::registration_performer_t

◆ impl::coop_private_iface_t

friend class impl::coop_private_iface_t
friend

Member Data Documentation

◆ m_agent_array

agent_array_t so_5::coop_t::m_agent_array
protected

Cooperation agents.

◆ m_coop_disp_binder

disp_binder_shptr_t so_5::coop_t::m_coop_disp_binder
protected

Default agent to the dispatcher binder.

◆ m_dereg_notificators

coop_dereg_notificators_container_ref_t so_5::coop_t::m_dereg_notificators
protected

Notificators for deregistration event.

Since
v.5.2.3

◆ m_dereg_reason

coop_dereg_reason_t so_5::coop_t::m_dereg_reason
protected

Deregistration reason.

Since
v.5.2.3

Receives actual value only in deregister() method.

◆ m_env

outliving_reference_t< environment_t > so_5::coop_t::m_env
protected

SObjectizer Environment for which cooperation is created.

◆ m_exception_reaction

exception_reaction_t so_5::coop_t::m_exception_reaction
protected
Initial value:

A reaction to non-handled exception.

Since
v.5.3.0

By default inherit_exception_reaction is used. It means that actual exception reaction should be provided by parent coop or by SO Environment.

◆ m_first_child

coop_shptr_t so_5::coop_t::m_first_child
protected

The head of list of children coops.

Since
v.5.6.0

◆ m_id

const coop_id_t so_5::coop_t::m_id
protected

Cooperation ID.

◆ m_lock

std::mutex so_5::coop_t::m_lock
protected

A lock for synchonization of some operations on coop.

A new way of handling coop registration was introduced in v.5.5.8. Agents from the coop cannot start its work before finish of main coop registration actions (expecialy before end of such important step as binding agents to dispatchers). But some agents could receive evt_start event before end of agents binding step. Those agents will be stopped on this lock.

Coop acquires this lock before agents binding step and releases just after that. Every agent tries to acquire it during handling of evt_start. If lock is belong to coop then an agent will be stopped until the lock will be released.

Since v.5.6.0 this lock is also used for protecting changes of coop's status and sibling's chain.

◆ m_next_sibling

coop_shptr_t so_5::coop_t::m_next_sibling
protected

The next coop in sibling's chain.

Can be nullptr if this coop is the last coop in the chain.

Note
This field will be used only by parent coop.
Since
v.5.6.0

◆ m_parent

coop_handle_t so_5::coop_t::m_parent
protected

Parent coop.

Note
This handle will be empty only for special root-coop. All other coops will have an actual parent (sometimes in the form of unvisible to user root-coop).

◆ m_prev_sibling

coop_shptr_t so_5::coop_t::m_prev_sibling
protected

The previous coop in sibling's chain.

Can be nullptr if this coop is the first coop in the chain.

Note
This field will be used only by parent coop.
Since
v.5.6.0

◆ m_reference_count

atomic_counter_t so_5::coop_t::m_reference_count { 0l }
protected

Count for entities.

Since v.5.2.3 this counter includes:

  • count of agents from cooperation;
  • count of direct child cooperations;
  • usage of cooperation pointer in cooperation registration routine.
See also
coop_t::increment_usage_count()

◆ m_reg_notificators

coop_reg_notificators_container_ref_t so_5::coop_t::m_reg_notificators
protected

Notificators for registration event.

Since
v.5.2.3

◆ m_registration_status

registration_status_t so_5::coop_t::m_registration_status
protected
Initial value:

The registration status of cooperation.

Since
v.5.2.3

By default cooperation has NOT_REGISTERED status. It is changed to REGISTERED after successfull completion of all registration-specific actions.

And then changed to DEREGISTERING when m_reference_count becames zero and final deregistration demand would be put to deregistration thread.

◆ m_resource_deleters

resource_deleter_vector_t so_5::coop_t::m_resource_deleters
protected

Container of user resource deleters.

Since
v.5.2.3

The documentation for this class was generated from the following file: