2
3
5#include <so_5/impl/mbox_core.hpp>
7#include <so_5/exception.hpp>
9#include <so_5/impl/local_mbox.hpp>
10#include <so_5/impl/named_local_mbox.hpp>
11#include <so_5/impl/mpsc_mbox.hpp>
12#include <so_5/impl/mchain_details.hpp>
13#include <so_5/impl/make_mchain.hpp>
38 auto id = ++m_mbox_id_counter;
39 if( !m_msg_tracing_stuff.get().is_msg_tracing_enabled() )
40 return mbox_t{
new local_mbox_without_tracing{ id, env } };
42 return mbox_t{
new local_mbox_with_tracing{ id, env, m_msg_tracing_stuff } };
53 default_global_mbox_namespace(),
54 mbox_name.giveout_value()
58 std::lock_guard< std::mutex > lock( m_dictionary_lock );
60 named_mboxes_dictionary_t::iterator it =
61 m_named_mboxes_dictionary.find( key );
63 if( m_named_mboxes_dictionary.end() != it )
68 new named_local_mbox_t( key, it->second.m_mbox, *
this )
73 ++(it->second.m_external_ref_count);
80 mbox_t mbox_ref = create_mbox( env );
85 new named_local_mbox_t( key, mbox_ref, *
this )
90 m_named_mboxes_dictionary.emplace(
92 named_mbox_info_t( mbox_ref ) );
100template<
typename M1,
typename M2,
typename... A >
106 std::unique_ptr< abstract_message_box_t > result;
108 if( !msg_tracing_stuff.get().is_msg_tracing_enabled() )
109 result.reset(
new M1{ std::forward<A>(args)... } );
112 new M2{ std::forward<A>(args)..., msg_tracing_stuff } );
124 const auto id = ++m_mbox_id_counter;
126 std::unique_ptr< abstract_message_box_t > actual_mbox =
128 ordinary_mpsc_mbox_without_tracing_t,
129 ordinary_mpsc_mbox_with_tracing_t >(
133 outliving_mutable( owner ) );
135 return mbox_t{ actual_mbox.release() };
143 const auto id = ++m_mbox_id_counter;
145 std::unique_ptr< abstract_message_box_t > actual_mbox =
147 limitless_mpsc_mbox_without_tracing_t,
148 limitless_mpsc_mbox_with_tracing_t >(
152 outliving_mutable( owner ) );
154 return mbox_t{ actual_mbox.release() };
161 std::lock_guard< std::mutex > lock( m_dictionary_lock );
163 named_mboxes_dictionary_t::iterator it =
164 m_named_mboxes_dictionary.find( name );
166 if( m_named_mboxes_dictionary.end() != it )
168 const unsigned int ref_count = --(it->second.m_external_ref_count);
170 m_named_mboxes_dictionary.erase( it );
179 const auto id = ++m_mbox_id_counter;
180 return creator.create(
181 mbox_creation_data_t{
182 outliving_mutable(env),
192 const std::function< mbox_t() > & mbox_factory )
197 std::string{ mbox_namespace.query_name() },
198 mbox_name.giveout_value()
205 std::lock_guard< std::mutex > lock( m_dictionary_lock );
207 named_mboxes_dictionary_t::iterator it =
208 m_named_mboxes_dictionary.find( key );
210 if( m_named_mboxes_dictionary.end() != it )
215 new named_local_mbox_t( key, it->second.m_mbox, *
this )
220 ++(it->second.m_external_ref_count);
228 auto fresh_mbox = mbox_factory();
231 rc_nullptr_as_result_of_user_mbox_factory,
232 "user-provided mbox_factory returns nullptr" );
237 std::lock_guard< std::mutex > lock( m_dictionary_lock );
241 named_mboxes_dictionary_t::iterator it =
242 m_named_mboxes_dictionary.find( key );
244 if( m_named_mboxes_dictionary.end() != it )
252 new named_local_mbox_t( key, it->second.m_mbox, *
this )
257 ++(it->second.m_external_ref_count);
264 new named_local_mbox_t( key, fresh_mbox, *
this )
269 m_named_mboxes_dictionary.emplace(
271 named_mbox_info_t( fresh_mbox ) );
287 auto id = ++m_mbox_id_counter;
289 if( params.capacity().unlimited() )
290 return make_mchain< unlimited_demand_queue >(
291 m_msg_tracing_stuff, params, env, id );
292 else if( memory_usage_t::dynamic == params.capacity().memory_usage() )
293 return make_mchain< limited_dynamic_demand_queue >(
294 m_msg_tracing_stuff, params, env, id );
296 return make_mchain< limited_preallocated_demand_queue >(
297 m_msg_tracing_stuff, params, env, id );
303 std::lock_guard< std::mutex > lock{ m_dictionary_lock };
305 return mbox_core_stats_t{ m_named_mboxes_dictionary.size() };
311 return ++m_mbox_id_counter;
Interface for creator of new mbox in OOP style.
mbox_t create_ordinary_mpsc_mbox(environment_t &env, agent_t &owner)
Create mpsc_mbox that handles message limits.
mbox_t create_limitless_mpsc_mbox(environment_t &env, agent_t &owner)
Create mpsc_mbox that ignores message limits.
mbox_t introduce_named_mbox(mbox_namespace_name_t mbox_namespace, nonempty_name_t mbox_name, const std::function< mbox_t() > &mbox_factory)
Introduce named mbox with user-provided factory.
mbox_core_t(outliving_reference_t< so_5::msg_tracing::holder_t > msg_tracing_stuff)
mbox_t create_custom_mbox(environment_t &env, ::so_5::custom_mbox_details::creator_iface_t &creator)
Create a custom mbox.
void destroy_mbox(const full_named_mbox_id_t &name) noexcept
Remove a reference to the named mbox.
mchain_t create_mchain(environment_t &env, const mchain_params_t ¶ms)
Create message chain.
mbox_t create_mbox(environment_t &env)
Create local anonymous mbox.
mbox_t create_mbox(environment_t &env, nonempty_name_t mbox_name)
Create local named mbox.
mbox_id_t allocate_mbox_id() noexcept
Allocate an ID for a new custom mbox or mchain.
mbox_core_stats_t query_stats()
Get statistics for run-time monitoring.
A class for the name of mbox_namespace.
Parameters for message chain.
Interface of holder of message tracer and message trace filter objects.
A class for the name which cannot be empty.
Helper class for indication of long-lived reference via its type.
#define SO_5_THROW_EXCEPTION(error_code, desc)
std::unique_ptr< abstract_message_box_t > make_actual_mbox(outliving_reference_t< so_5::msg_tracing::holder_t > msg_tracing_stuff, A &&... args)
Details of SObjectizer run-time implementations.
Various properties and parameters of message chains.
Public part of message delivery tracing mechanism.
Private part of message limit implementation.
Full name for a named mbox.
Statistics from mbox_core for run-time monitoring.