Another constructor for wrapped_env_t that waits completion of init-function
eao197 opened this issue · comments
There is a tricky moment with the use of wrapped_env_t
constructor with init function:
so_5::mbox_t target_mbox;
so_5::wrapped_env_t sobjectizer{
[&](so_5::environment_t & env) {
env.introduce_coop([&](so_5::coop_t & coop) {
target_mbox = coop.make_agent<my_agent>(...)->so_direct_mbox(); // (1)
});
}
};
so_5::send<my_message>(target_mbox, ...); // (2)
There is no guarantee that code at point (1) completes before invocation of so_5::send
at point (2). Moreover, there could be a data race, because target_mbox
may be modified at (1) while it's used at (2).
The correct way is:
std::promise<so_5::mbox_t> target_mbox_promise;
so_5::wrapped_env_t sobjectizer{
[&](so_5::environment_t & env) {
env.introduce_coop([&](so_5::coop_t & coop) {
target_mbox_promise.set_value( coop.make_agent<my_agent>(...)->so_direct_mbox() ); // (1)
});
}
};
so_5::mbox_t target_mbox = target_mbox_promise.get_future().get();
so_5::send<my_message>(target_mbox, ...); // (2)
But such code is more complicated.
May be another constructor of wrapped_env_t can help?
Something like:
so_5::mbox_t target_mbox;
so_5::wrapped_env_t sobjectizer{
so_5::wrapped_env_t::wait_init_completion, // This has to be added!
[&](so_5::environment_t & env) {
env.introduce_coop([&](so_5::coop_t & coop) {
target_mbox = coop.make_agent<my_agent>(...)->so_direct_mbox(); // (1)
});
}
};
so_5::send<my_message>(target_mbox, ...); // (2)
The use of so_5::wrapped_env_t::wait_init_completion
dictated to suspend the calling thread until init-function completes its work.
It's a part of SO-5.8.2 release.