Skip to content

Commit

Permalink
The very first step in resolving #71.
Browse files Browse the repository at this point in the history
A draft version of agent_t::so_this_agent_disp_binder() and a unit-test
for it.
  • Loading branch information
eao197 committed Oct 13, 2023
1 parent 6a0302f commit c787155
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 0 deletions.
8 changes: 8 additions & 0 deletions dev/so_5/agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2604,6 +2604,14 @@ class SO_5_TYPE agent_t
return lambda();
}

//FIXME: document this!
[[nodiscard]]
disp_binder_shptr_t
so_this_agent_disp_binder() const
{
return m_disp_binder;
}

private:
const state_t st_default{ self_ptr(), "<DEFAULT>" };

Expand Down
1 change: 1 addition & 0 deletions dev/test/so_5/coop/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ add_subdirectory(child_coop_map)
add_subdirectory(issue_28)
add_subdirectory(msg_loss_at_registration)
add_subdirectory(destruction_order_1)
add_subdirectory(this_agent_disp_binder)
1 change: 1 addition & 0 deletions dev/test/so_5/coop/build_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
required_prj( "#{path}/issue_28/prj.ut.rb" )
required_prj( "#{path}/msg_loss_at_registration/prj.ut.rb" )
required_prj( "#{path}/destruction_order_1/prj.ut.rb" )
required_prj( "#{path}/this_agent_disp_binder/prj.ut.rb" )
}

2 changes: 2 additions & 0 deletions dev/test/so_5/coop/this_agent_disp_binder/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set(UNITTEST _unit.test.coop.this_agent_disp_binder)
include(${CMAKE_SOURCE_DIR}/cmake/unittest.cmake)
145 changes: 145 additions & 0 deletions dev/test/so_5/coop/this_agent_disp_binder/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* A unit-test for agent_t::so_this_agent_disp_binder().
*/

#include <so_5/all.hpp>

#include <test/3rd_party/various_helpers/ensure.hpp>
#include <test/3rd_party/various_helpers/time_limited_execution.hpp>

namespace test
{

struct msg_done final : public so_5::signal_t {};

struct msg_take_tid final : public so_5::message_t
{
so_5::current_thread_id_t m_tid;

explicit msg_take_tid( so_5::current_thread_id_t tid )
: m_tid{ tid }
{}
};

class a_collector_t final : public so_5::agent_t
{
std::set< so_5::current_thread_id_t > m_tids;

public:
using so_5::agent_t::agent_t;

void
so_define_agent() override
{
so_subscribe_self()
.event( &a_collector_t::evt_done )
.event( &a_collector_t::evt_take_tid )
;
}

void
so_evt_start() override
{
so_5::send< msg_take_tid >( *this, so_5::query_current_thread_id() );
}

void
so_evt_finish() override
{
ensure_or_die( 3u == m_tids.size(),
"unexpected number of collected TIDs: " +
std::to_string( m_tids.size() ) );
}

private:
void
evt_done( mhood_t< msg_done > )
{
so_deregister_agent_coop_normally();
}

void
evt_take_tid( mhood_t< msg_take_tid > cmd )
{
m_tids.insert( cmd->m_tid );
}
};

class a_child_t final : public so_5::agent_t
{
const so_5::mbox_t m_collector_mbox;

public:
a_child_t( context_t ctx, so_5::mbox_t collector_mbox )
: so_5::agent_t{ std::move(ctx) }
, m_collector_mbox{ std::move(collector_mbox) }
{}

void
so_evt_start() override
{
so_5::send< msg_take_tid >( m_collector_mbox,
so_5::query_current_thread_id() );
so_5::send< msg_done >( m_collector_mbox );
}
};

class a_parent_t final : public so_5::agent_t
{
const so_5::mbox_t m_collector_mbox;

public:
a_parent_t( context_t ctx, so_5::mbox_t collector_mbox )
: so_5::agent_t{ std::move(ctx) }
, m_collector_mbox{ std::move(collector_mbox) }
{}

void
so_evt_start() override
{
so_5::send< msg_take_tid >( m_collector_mbox,
so_5::query_current_thread_id() );

so_5::introduce_child_coop(
*this,
so_this_agent_disp_binder(),
[this]( so_5::coop_t & coop ) {
coop.make_agent< a_child_t >( m_collector_mbox );
} );
}
};

void
init( so_5::environment_t & env )
{
env.introduce_coop( [&]( so_5::coop_t & coop ) {
// The collector will use the default dispatcher
// (because it's automatically selected for the coop).
auto mbox = coop.make_agent< a_collector_t >()->so_direct_mbox();

// The parent agent will use active_obj dispatcher.
coop.make_agent_with_binder< a_parent_t >(
so_5::disp::active_obj::make_dispatcher( env ).binder(),
mbox );
} );
}

} /* namespace test */

int
main()
{
try
{
run_with_time_limit( []{ so_5::launch( test::init ); }, 5 );

return 0;
}
catch( const std::exception & x )
{
std::cerr << "Exception: " << x.what() << std::endl;
}

return 2;
}

11 changes: 11 additions & 0 deletions dev/test/so_5/coop/this_agent_disp_binder/prj.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'mxx_ru/cpp'

MxxRu::Cpp::exe_target {

required_prj 'so_5/prj.rb'

target '_unit.test.coop.this_agent_disp_binder'

cpp_source 'main.cpp'
}

9 changes: 9 additions & 0 deletions dev/test/so_5/coop/this_agent_disp_binder/prj.ut.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'mxx_ru/binary_unittest'

path = 'test/so_5/coop/this_agent_disp_binder'

MxxRu::setup_target(
MxxRu::BinaryUnittestTarget.new(
"#{path}/prj.ut.rb",
"#{path}/prj.rb" )
)

0 comments on commit c787155

Please sign in to comment.