Skip to content

Another constructor for wrapped_env_t that waits completion of init-function #74

@eao197

Description

@eao197

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions