]> AND Private Git Repository - loba.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Terminate smoothly on CTRL-C.
authorArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Fri, 25 Feb 2011 14:21:28 +0000 (15:21 +0100)
committerArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Fri, 25 Feb 2011 14:22:54 +0000 (15:22 +0100)
TODO
main.cpp
options.cpp
options.h
process.cpp

diff --git a/TODO b/TODO
index 50395d15266171ac72c1adbc2780e4b5dabbddb7..0d476f49b6f3ff0e3bf14a98c9a9e41a6ffbcc56 100644 (file)
--- a/TODO
+++ b/TODO
@@ -9,8 +9,6 @@
 * Implement some random initial distribution of load
    Options -r seed, -R [algo ?]
 
-* Terminate smoothly on ctrl+c.
-
 * Support heterogeneous platforms?
    Not sure yet.
    Should be doable if each process also sends its speed to its neighbors.
index ff1fa1bb27f0708b1f2eb1b9ecac24c9e41f7b24..76125e9db0b639a3d7e027b6b5ceb7c99d637c04 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -1,5 +1,7 @@
-#include <cstring>
+#include <cerrno>
+#include <cstring>              // strchr
 #include <iostream>
+#include <signal.h>
 #include <stdexcept>
 #include <msg/msg.h>
 #include <xbt/log.h>
@@ -36,6 +38,7 @@ namespace {
         EXIT_FAILURE_INIT  = 0x02,  // failed to initialize simulator
         EXIT_FAILURE_SIMU  = 0x04,  // simulation failed
         EXIT_FAILURE_CLEAN = 0x08,  // error at cleanup
+        EXIT_FAILURE_OTHER = 0x10,  // other error
     };
 
     // Cannot be globally initialized...
@@ -131,6 +134,28 @@ static void check_for_lost_load()
                  total_running, running_ratio);
 }
 
+static void signal_handler(int /*sig*/)
+{
+    if (!opt::exit_request) {
+        XBT_CRITICAL(">>>>>>>>>>"
+                     " caught CTRL-C: global exit requested "
+                     "<<<<<<<<<<");
+        opt::exit_request = true;
+    }
+}
+
+static void install_signal_handler()
+{
+    struct sigaction action;
+    action.sa_handler = signal_handler;
+    sigemptyset(&action.sa_mask);
+    action.sa_flags = SA_RESTART;
+    if (sigaction (SIGINT, &action, NULL) == -1) {
+        std::cerr << "sigaction: " << strerror(errno) << "\n";
+        exit(EXIT_FAILURE_OTHER);
+    }
+}
+
 #define PR_STATS(descr, st)                                             \
     XBT_INFO("| %.*s: %g / %g / %g", DATA_DESCR_WIDTH,                  \
              descr " (total/avg./stddev)................................", \
@@ -162,6 +187,7 @@ int main(int argc, char* argv[])
     // Note: MSG_global_init() may throw an exception, but it seems
     // impossible to catch it correctly :-(
     MSG_global_init(&argc, argv);
+    install_signal_handler();
 
     // Parse global parameters
     bool parse_res = opt::parse_args(&argc, argv);
index c0becfde198f7347b31ff3593c95447697975077..2994640bf6e7f0c766ea6ca66637bcbd5ab804a7 100644 (file)
@@ -35,6 +35,7 @@ namespace opt {
 
     // Simulation parameters
     int log_rate = 1;
+    bool exit_request = false;
 
     // Platform and deployment
     std::string platform_file;
index b3e30816f0c127d4b935d706f408fd7436c9a6cb..0abec0f2e5ef0fe78e1c1802b666dbb62375177c 100644 (file)
--- a/options.h
+++ b/options.h
@@ -22,6 +22,7 @@ namespace opt {
 
     // Simulation parameters
     extern int log_rate;
+    extern bool exit_request;
 
     // Platform and deployment
     extern std::string platform_file;
index d0bfc21120b8cbc8ea0230b4eb9bb97e4eeb26f3..cbf512b6b66d2fde431d060030cf072868b942e2 100644 (file)
@@ -224,6 +224,10 @@ bool process::still_running()
     if (!last_status) {
         /* nop */
 
+    } else if (opt::exit_request) {
+        XBT_VERB("Global exit requested");
+        last_status = false;
+
     } else if (opt::time_limit && MSG_get_clock() >= opt::time_limit) {
         XBT_VERB("Reached time limit: %g/%g", MSG_get_clock(), opt::time_limit);
         last_status = false;