*/
smx_actor_t SIMIX_process_self()
{
- smx_context_t self_context = simgrid::kernel::context::Context::self();
+ simgrid::kernel::context::Context* self_context = simgrid::kernel::context::Context::self();
return (self_context != nullptr) ? self_context->get_actor() : nullptr;
}
context->attach_start();
/* The on_creation() signal must be delayed until there, where the pid and everything is set */
- simgrid::s4u::ActorPtr tmp = actor->iface(); // Passing this directly to on_creation will lead to crashes
- simgrid::s4u::Actor::on_creation(tmp);
+ simgrid::s4u::Actor::on_creation(*actor->ciface());
return ActorImplPtr(actor);
}
void ActorImpl::cleanup()
{
+ finished_ = true;
+
+ if (has_to_auto_restart() && not get_host()->is_on()) {
+ XBT_DEBUG("Insert host %s to watched_hosts because it's off and %s needs to restart", get_host()->get_cname(),
+ get_cname());
+ watched_hosts.insert(get_host()->get_name());
+ }
+
+ // Execute the termination callbacks
+ smx_process_exit_status_t exit_status = (context_->iwannadie) ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
+ while (not on_exit.empty()) {
+ s_smx_process_exit_fun_t exit_fun = on_exit.back();
+ on_exit.pop_back();
+ (exit_fun.fun)(exit_status, exit_fun.arg);
+ }
+
+ /* cancel non-blocking activities */
+ for (auto activity : comms)
+ boost::static_pointer_cast<activity::CommImpl>(activity)->cancel();
+ comms.clear();
+
+ XBT_DEBUG("%s@%s(%ld) should not run anymore", get_cname(), get_host()->get_cname(), get_pid());
+
if (this == simix_global->maestro_process) /* Do not cleanup maestro */
return;
XBT_DEBUG("Cleanup actor %s (%p), waiting synchro %p", get_cname(), this, waiting_synchro.get());
+ /* Unregister from the kill timer if any */
+ if (kill_timer != nullptr) {
+ kill_timer->remove();
+ kill_timer = nullptr;
+ }
+
simix_global->mutex.lock();
simix_global->process_list.erase(pid_);
simgrid::xbt::intrusive_erase(host_->pimpl_->process_list_, *this);
if (not smx_destroy_list_hook.is_linked()) {
#if SIMGRID_HAVE_MC
- xbt_dynar_push_as(simix_global->dead_actors_vector, smx_actor_t, this);
+ xbt_dynar_push_as(simix_global->dead_actors_vector, ActorImpl*, this);
#endif
simix_global->actors_to_destroy.push_back(*this);
}
- context_->iwannadie = false;
simix_global->mutex.unlock();
+
+ context_->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
+ simgrid::simix::simcall([this] { simgrid::s4u::Actor::on_destruction(*ciface()); });
+ context_->iwannadie = true;
}
void ActorImpl::exit()
XBT_DEBUG("Control returned to me: '%s'", get_cname());
if (context_->iwannadie) {
-
XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname());
// throw simgrid::kernel::context::ForcefulKillException(); Does not seem to properly kill the actor
context_->stop();
s4u::Actor* ActorImpl::restart()
{
+ xbt_assert(this != simix_global->maestro_process, "Restarting maestro is not supported");
+
XBT_DEBUG("Restarting actor %s on %s", get_cname(), host_->get_cname());
// retrieve the arguments of the old actor
ProcessArg arg = ProcessArg(host_, this);
// kill the old actor
- (this == simix_global->maestro_process) ? this->exit() : SIMIX_process_self()->kill(this);
+ context::Context::self()->get_actor()->kill(this);
// start the new actor
ActorImplPtr actor =
XBT_OUT();
}
-activity::ActivityImplPtr ActorImpl::join(smx_actor_t actor, double timeout)
+activity::ActivityImplPtr ActorImpl::join(ActorImpl* actor, double timeout)
{
activity::ActivityImplPtr res = this->sleep(timeout);
intrusive_ptr_add_ref(res.get());
SIMIX_process_on_exit(actor,
[](int, void* arg) {
- auto sleep = static_cast<simgrid::kernel::activity::SleepImpl*>(arg);
+ auto sleep = static_cast<activity::SleepImpl*>(arg);
if (sleep->surf_action_)
- sleep->surf_action_->finish(simgrid::kernel::resource::Action::State::FINISHED);
+ sleep->surf_action_->finish(resource::Action::State::FINISHED);
intrusive_ptr_release(sleep);
},
res.get());
throw_exception(std::make_exception_ptr(simgrid::HostFailureException(
XBT_THROW_POINT, std::string("Host ") + host_->get_cname() + " failed, you cannot sleep there.")));
- return simgrid::kernel::activity::SleepImplPtr(new simgrid::kernel::activity::SleepImpl("sleep", host_))
- ->start(duration);
+ return activity::SleepImplPtr(new activity::SleepImpl())
+ ->set_name("sleep")
+ ->set_host(host_)
+ ->set_duration(duration)
+ ->start();
}
void ActorImpl::throw_exception(std::exception_ptr e)
activity::SleepImplPtr sleep = boost::dynamic_pointer_cast<activity::SleepImpl>(waiting_synchro);
if (sleep != nullptr) {
- SIMIX_process_sleep_destroy(waiting_synchro);
+ SIMIX_process_sleep_destroy(sleep);
if (std::find(begin(simix_global->actors_to_run), end(simix_global->actors_to_run), this) ==
end(simix_global->actors_to_run) &&
this != SIMIX_process_self()) {
void ActorImpl::set_host(s4u::Host* dest)
{
- simgrid::xbt::intrusive_erase(host_->pimpl_->process_list_, *this);
+ xbt::intrusive_erase(host_->pimpl_->process_list_, *this);
host_ = dest;
dest->pimpl_->process_list_.push_back(*this);
}
ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host)
{
- ActorImpl* actor = new ActorImpl(simgrid::xbt::string(name), host);
+ ActorImpl* actor = new ActorImpl(xbt::string(name), host);
actor->set_ppid(this->pid_);
intrusive_ptr_add_ref(actor);
/* The on_creation() signal must be delayed until there, where the pid and everything is set */
- s4u::Actor::on_creation(actor->iface());
+ s4u::Actor::on_creation(*actor->ciface());
return ActorImplPtr(actor);
}
ActorImplPtr actor;
if (parent_actor != nullptr)
- actor = parent_actor->init(simgrid::xbt::string(name), host);
+ actor = parent_actor->init(xbt::string(name), host);
else
- actor = SIMIX_process_self()->init(simgrid::xbt::string(name), host);
+ actor = SIMIX_process_self()->init(xbt::string(name), host);
/* actor data */
actor->set_user_data(data);
simgrid::kernel::activity::SleepImplPtr sleep =
boost::dynamic_pointer_cast<simgrid::kernel::activity::SleepImpl>(actor->waiting_synchro);
if (sleep != nullptr) {
- SIMIX_process_sleep_destroy(actor->waiting_synchro);
+ SIMIX_process_sleep_destroy(sleep);
if (std::find(begin(simix_global->actors_to_run), end(simix_global->actors_to_run), actor) ==
end(simix_global->actors_to_run) &&
actor != SIMIX_process_self()) {
simcall->issuer->waiting_synchro = sync;
}
-void SIMIX_process_sleep_destroy(smx_activity_t synchro)
+void SIMIX_process_sleep_destroy(simgrid::kernel::activity::SleepImplPtr sleep)
{
- XBT_DEBUG("Destroy sleep synchro %p", synchro.get());
- simgrid::kernel::activity::SleepImplPtr sleep =
- boost::static_pointer_cast<simgrid::kernel::activity::SleepImpl>(synchro);
+ XBT_DEBUG("Destroy sleep synchro %p", sleep.get());
if (sleep->surf_action_) {
sleep->surf_action_->unref();