undaemonize();
- while (not mailboxes.empty())
- mailboxes.back()->set_receiver(nullptr);
+ while (not mailboxes_.empty())
+ mailboxes_.back()->set_receiver(nullptr);
}
/* Do all the cleanups from the actor context. Warning, the simcall mechanism was not reignited so doing simcalls in
void ActorImpl::cleanup_from_self()
{
xbt_assert(not ActorImpl::is_maestro(), "Cleanup_from_self called from maestro on '%s'", get_cname());
- context_->set_to_be_freed();
+ set_to_be_freed();
if (on_exit) {
// Execute the termination callbacks
- bool failed = context_->wannadie();
+ bool failed = wannadie();
for (auto exit_fun = on_exit->crbegin(); exit_fun != on_exit->crend(); ++exit_fun)
(*exit_fun)(failed);
on_exit.reset();
simcall_.timeout_cb_ = nullptr;
}
- context_->set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
+ set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
actor::simcall_answered([this] { s4u::Actor::on_termination(*get_ciface()); });
- context_->set_wannadie();
+ set_wannadie();
}
void ActorImpl::exit()
{
- context_->set_wannadie();
+ set_wannadie();
suspended_ = false;
exception_ = nullptr;
- /* destroy the blocking synchro if any */
- if (auto activity = waiting_synchro_) {
- activities_.remove(waiting_synchro_);
- waiting_synchro_ = nullptr;
-
+ if (waiting_synchro_ != nullptr) {
+ /* Take an extra reference on the activity object that may be unref by Comm::finish() or friends */
+ activity::ActivityImplPtr activity = waiting_synchro_;
activity->cancel();
activity->set_state(activity::State::FAILED);
activity->post();
+
+ activities_.remove(waiting_synchro_);
+ waiting_synchro_ = nullptr;
}
for (auto const& activity : activities_)
activity->cancel();
activities_.clear();
- while (not mailboxes.empty())
- mailboxes.back()->set_receiver(nullptr);
-
// Forcefully kill the actor if its host is turned off. Not a HostFailureException because you should not survive that
this->throw_exception(std::make_exception_ptr(ForcefulKillException(host_->is_on() ? "exited" : "host failed")));
}
void ActorImpl::kill(ActorImpl* actor) const
{
xbt_assert(not actor->is_maestro(), "Killing maestro is a rather bad idea.");
- if (actor->context_->wannadie()) {
+ if (actor->wannadie()) {
XBT_DEBUG("Ignoring request to kill actor %s@%s that is already dead", actor->get_cname(),
actor->host_->get_cname());
return;
kill_timer_ = timer::Timer::set(kill_time, [this] {
this->exit();
kill_timer_ = nullptr;
+ EngineImpl::get_instance()->add_actor_to_run_list(this);
});
}
/* Ok, maestro returned control to us */
XBT_DEBUG("Control returned to me: '%s'", get_cname());
- if (context_->wannadie()) {
+ if (wannadie()) {
XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname());
context_->stop();
THROW_IMPOSSIBLE;
}
}
#if HAVE_SMPI
- if (not context_->wannadie())
+ if (not wannadie())
smpi_switch_data_segment(get_iface());
#endif
}
{
XBT_IN("actor = %p", this);
- if (context_->wannadie()) {
+ if (wannadie()) {
XBT_VERB("Ignoring request to resume an actor that is currently dying.");
return;
}
activity::ActivityImplPtr ActorImpl::join(const ActorImpl* actor, double timeout)
{
activity::ActivityImplPtr sleep = this->sleep(timeout);
- actor->on_exit->emplace_back([sleep](bool) {
+ if (actor->wannadie() || actor->to_be_freed()) {
if (sleep->surf_action_)
sleep->surf_action_->finish(resource::Action::State::FINISHED);
- });
+ } else {
+ actor->on_exit->emplace_back([sleep](bool) {
+ if (sleep->surf_action_)
+ sleep->surf_action_->finish(resource::Action::State::FINISHED);
+ });
+ }
return sleep;
}
actor->daemonize();
return actor;
}
+void ActorImpl::set_wannadie(bool value)
+{
+ XBT_DEBUG("Actor %s gonna die.", get_cname());
+ iwannadie_ = value;
+}
void create_maestro(const std::function<void()>& code)
{