Main changes:
* don't modify (clean) the on_exit vector on cleanup, but detach its shared_ptr instead;
* define ActorImpl::undaemonize() for daemon cleanup, and use it instead of using an
on_exit callback (ensures that it is not added multiple times);
* complete test 'tesh-s4u-actor-autorestart' with an auto-restarting daemon.
watched_hosts.insert(get_host()->get_name());
}
watched_hosts.insert(get_host()->get_name());
}
- // Execute the termination callbacks
- bool failed = context_->iwannadie;
- for (auto exit_fun = on_exit->crbegin(); exit_fun != on_exit->crend(); ++exit_fun)
- (*exit_fun)(failed);
- if (not has_to_auto_restart())
- on_exit->clear();
+ if (on_exit) {
+ // Execute the termination callbacks
+ bool failed = context_->iwannadie;
+ for (auto exit_fun = on_exit->crbegin(); exit_fun != on_exit->crend(); ++exit_fun)
+ (*exit_fun)(failed);
+ on_exit.reset();
+ }
+ undaemonize();
/* cancel non-blocking activities */
for (auto activity : comms)
/* cancel non-blocking activities */
for (auto activity : comms)
if (not daemon_) {
daemon_ = true;
simix_global->daemons.push_back(this);
if (not daemon_) {
daemon_ = true;
simix_global->daemons.push_back(this);
- SIMIX_process_on_exit(this, [this](bool) {
- auto& vect = simix_global->daemons;
- auto it = std::find(vect.begin(), vect.end(), this);
- xbt_assert(it != vect.end(), "The dying daemon is not a daemon after all. Please report that bug.");
-
- /* Don't move the whole content since we don't really care about the order */
- std::swap(*it, vect.back());
- vect.pop_back();
- });
+ }
+}
+
+void ActorImpl::undaemonize()
+{
+ if (daemon_) {
+ auto& vect = simix_global->daemons;
+ auto it = std::find(vect.begin(), vect.end(), this);
+ xbt_assert(it != vect.end(), "The dying daemon is not a daemon after all. Please report that bug.");
+ /* Don't move the whole content since we don't really care about the order */
+
+ std::swap(*it, vect.back());
+ vect.pop_back();
+ daemon_ = false;
std::list<activity::ActivityImplPtr> comms; /* the current non-blocking communication synchros */
s_smx_simcall simcall;
/* list of functions executed when the process dies */
std::list<activity::ActivityImplPtr> comms; /* the current non-blocking communication synchros */
s_smx_simcall simcall;
/* list of functions executed when the process dies */
- const std::shared_ptr<std::vector<std::function<void(bool)>>> on_exit =
+ std::shared_ptr<std::vector<std::function<void(bool)>>> on_exit =
std::make_shared<std::vector<std::function<void(bool)>>>();
std::function<void()> code;
std::make_shared<std::vector<std::function<void(bool)>>>();
std::function<void()> code;
/* S4U/implem interfaces */
private:
s4u::Actor piface_; // Our interface is part of ourselves
/* S4U/implem interfaces */
private:
s4u::Actor piface_; // Our interface is part of ourselves
+
+ void undaemonize();
+
public:
s4u::ActorPtr iface() { return s4u::ActorPtr(&piface_); }
s4u::Actor* ciface() { return &piface_; }
public:
s4u::ActorPtr iface() { return s4u::ActorPtr(&piface_); }
s4u::Actor* ciface() { return &piface_; }
+static void dummy_daemon()
+{
+ simgrid::s4u::Actor::self()->daemonize();
+ while (1) {
+ XBT_INFO("Hello from the infinite loop");
+ simgrid::s4u::this_actor::sleep_for(80.0);
+ }
+}
+
static void autostart()
{
simgrid::s4u::Host* host = simgrid::s4u::Host::by_name("Fafard");
static void autostart()
{
simgrid::s4u::Host* host = simgrid::s4u::Host::by_name("Fafard");
- XBT_INFO("starting a dummy process on %s ", host->get_cname());
+ XBT_INFO("starting a dummy process on %s", host->get_cname());
simgrid::s4u::ActorPtr dummy_actor = simgrid::s4u::Actor::create("Dummy", host, dummy);
dummy_actor->on_exit([](bool) { XBT_INFO("On_exit callback set before autorestart"); });
dummy_actor->set_auto_restart(true);
dummy_actor->on_exit([](bool) { XBT_INFO("On_exit callback set after autorestart"); });
simgrid::s4u::ActorPtr dummy_actor = simgrid::s4u::Actor::create("Dummy", host, dummy);
dummy_actor->on_exit([](bool) { XBT_INFO("On_exit callback set before autorestart"); });
dummy_actor->set_auto_restart(true);
dummy_actor->on_exit([](bool) { XBT_INFO("On_exit callback set after autorestart"); });
+ XBT_INFO("starting a daemon process on %s", host->get_cname());
+ simgrid::s4u::ActorPtr daemon_actor = simgrid::s4u::Actor::create("Daemon", host, dummy_daemon);
+ daemon_actor->on_exit([](bool) { XBT_INFO("On_exit callback set before autorestart"); });
+ daemon_actor->set_auto_restart(true);
+ daemon_actor->on_exit([](bool) { XBT_INFO("On_exit callback set after autorestart"); });
+
simgrid::s4u::this_actor::sleep_for(50);
XBT_INFO("powering off %s", host->get_cname());
simgrid::s4u::this_actor::sleep_for(50);
XBT_INFO("powering off %s", host->get_cname());
$ ./actor-autorestart ${platfdir}/small_platform.xml
$ ./actor-autorestart ${platfdir}/small_platform.xml
-> [Tremblay:Autostart:(1) 0.000000] [s4u_test/INFO] starting a dummy process on Fafard
+> [Tremblay:Autostart:(1) 0.000000] [s4u_test/INFO] starting a dummy process on Fafard
> [Fafard:Dummy:(2) 0.000000] [s4u_test/INFO] I start
> [Fafard:Dummy:(2) 0.000000] [s4u_test/INFO] I start
+> [Tremblay:Autostart:(1) 0.000000] [s4u_test/INFO] starting a daemon process on Fafard
+> [Fafard:Daemon:(3) 0.000000] [s4u_test/INFO] Hello from the infinite loop
> [Tremblay:Autostart:(1) 50.000000] [s4u_test/INFO] powering off Fafard
> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] On_exit callback set after autorestart
> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] On_exit callback set before autorestart
> [Tremblay:Autostart:(1) 50.000000] [s4u_test/INFO] powering off Fafard
> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] On_exit callback set after autorestart
> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Daemon:(3) 50.000000] [s4u_test/INFO] On_exit callback set after autorestart
+> [Fafard:Daemon:(3) 50.000000] [s4u_test/INFO] On_exit callback set before autorestart
> [Tremblay:Autostart:(1) 60.000000] [s4u_test/INFO] powering on Fafard
> [Tremblay:Autostart:(1) 60.000000] [s4u_test/INFO] powering on Fafard
-> [Fafard:Dummy:(3) 60.000000] [s4u_test/INFO] I start
-> [Fafard:Dummy:(3) 260.000000] [s4u_test/INFO] I stop
-> [Fafard:Dummy:(3) 260.000000] [s4u_test/INFO] On_exit callback set after autorestart
-> [Fafard:Dummy:(3) 260.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Dummy:(4) 60.000000] [s4u_test/INFO] I start
+> [Fafard:Daemon:(5) 60.000000] [s4u_test/INFO] Hello from the infinite loop
+> [Fafard:Daemon:(5) 140.000000] [s4u_test/INFO] Hello from the infinite loop
+> [Fafard:Daemon:(5) 220.000000] [s4u_test/INFO] Hello from the infinite loop
+> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] I stop
+> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] On_exit callback set after autorestart
+> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Daemon:(5) 260.000000] [s4u_test/INFO] On_exit callback set after autorestart
+> [Fafard:Daemon:(5) 260.000000] [s4u_test/INFO] On_exit callback set before autorestart
> [260.000000] [s4u_test/INFO] Simulation time 260
> [260.000000] [s4u_test/INFO] Simulation time 260