X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/4de2a148bea34f550b79c07fb5e80ac36e6aa0e9..84f504218e6e541881d121ba0382f132ff1cf135:/src/kernel/actor/ActorImpl.cpp diff --git a/src/kernel/actor/ActorImpl.cpp b/src/kernel/actor/ActorImpl.cpp index 7551774338..8acb38fa1c 100644 --- a/src/kernel/actor/ActorImpl.cpp +++ b/src/kernel/actor/ActorImpl.cpp @@ -157,8 +157,8 @@ void ActorImpl::cleanup_from_kernel() 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 @@ -166,11 +166,11 @@ void ActorImpl::cleanup_from_kernel() 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(); @@ -193,33 +193,31 @@ void ActorImpl::cleanup_from_self() 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"))); } @@ -227,7 +225,7 @@ void ActorImpl::exit() 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; @@ -259,6 +257,7 @@ void ActorImpl::set_kill_time(double kill_time) kill_timer_ = timer::Timer::set(kill_time, [this] { this->exit(); kill_timer_ = nullptr; + EngineImpl::get_instance()->add_actor_to_run_list(this); }); } @@ -276,7 +275,7 @@ void ActorImpl::yield() /* 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; @@ -299,7 +298,7 @@ void ActorImpl::yield() } } #if HAVE_SMPI - if (not context_->wannadie()) + if (not wannadie()) smpi_switch_data_segment(get_iface()); #endif } @@ -355,7 +354,7 @@ void ActorImpl::resume() { XBT_IN("actor = %p", this); - if (context_->wannadie()) { + if (wannadie()) { XBT_VERB("Ignoring request to resume an actor that is currently dying."); return; } @@ -376,10 +375,15 @@ void ActorImpl::resume() 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; } @@ -502,6 +506,11 @@ ActorImplPtr ActorImpl::create(ProcessArg* args) 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& code) {