Browse Source

Changes the way SIGINT and SIGTERM are handled to gracefully exit upon
interruption

Caleb Fangmeier 6 years ago
parent
commit
26472a33ce

+ 1 - 1
include/container.hpp

@@ -59,7 +59,7 @@ namespace fv::util {
         _map[typeid(std::map<std::string, std::string>)] = "std::map<std::string,std::string>";
 
         if (_map[index] == "") {
-            CRITICAL("Cannot lookup type name of \"" << index.name() << "\"", -1);
+            CRITICAL("Cannot lookup type name of \"" << index.name() << "\"");
         }
         return _map[index];
     }

+ 27 - 3
include/dataset.hpp

@@ -31,7 +31,13 @@
 #ifndef dataset_hpp
 #define dataset_hpp
 #include <iostream>
+#include <functional>
+
 #include <sys/time.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+
 #include "value.hpp"
 #include "container.hpp"
 #include "memtrack.hpp"
@@ -42,6 +48,10 @@
 
 namespace fv {
 
+    void request_stop_callback(int);  // Forward Declaration
+    class DataSet;  // Forward Declaration
+    DataSet* the_dataset;
+
 /*
  * A DataSet is a generic source of data that is used to populate
  * ObservedValues. For each ObservedValue, it is recommended that the DataSet
@@ -57,6 +67,7 @@ namespace fv {
         }
 
         timeval start_time;
+        bool stop_requested;
 
         void print_status() {
             size_t m_used = fv_util::getCurrentRSS() / 1024 / 1024;
@@ -110,11 +121,16 @@ namespace fv {
         virtual void save_config() = 0;
 
     public:
-        DataSet() {
+        DataSet() : stop_requested(false){
             max_events = fv_util::the_config->get_max_events();
+            the_dataset = this;
+
+            signal(SIGINT, request_stop_callback);
+            signal(SIGTERM, request_stop_callback);
         }
 
         bool next(bool verbose=true) {
+            if (stop_requested) return false;
             int current_event = get_current_event();
             if (current_event == 0) gettimeofday(&start_time, nullptr);
             if (verbose and (((current_event + 1) % 500) == 0 or current_event+1 == get_events())) print_status();
@@ -130,6 +146,10 @@ namespace fv {
             return this->max_events;
         }
 
+        void request_stop() {
+            stop_requested = true;
+        }
+
         virtual void save_all() {
             for (auto container : containers)
                 container.second->save();
@@ -140,7 +160,7 @@ namespace fv {
         C *register_container(ArgTypes... args) {
             C *container = new C(args...);
             if (containers[container->get_name()] != nullptr) {
-                CRITICAL("Container with name \"" + container->get_name() + "\" already exists.", -1);
+                CRITICAL("Container with name \"" + container->get_name() + "\" already exists.");
             }
             containers[container->get_name()] = container;
             return container;
@@ -149,11 +169,15 @@ namespace fv {
         GenContainer *get_container(std::string container_name) {
             GenContainer *c = containers[container_name];
             if (c == nullptr) {
-                CRITICAL("Request for container \"" << container_name << "\" failed. Doesn't exist.", -1);
+                CRITICAL("Request for container \"" << container_name << "\" failed. Doesn't exist.");
             }
             return c;
         }
     };
 
+    void request_stop_callback(int) {
+        std::cout << std::endl << "SIGINT/SIGTERM caught, stopping after current event" << std::endl;
+        the_dataset->request_stop();
+    }
 }
 #endif // dataset_hpp

+ 1 - 1
include/filval.hpp

@@ -17,7 +17,7 @@ namespace fv {
         if (tv == nullptr) {
             CRITICAL("Could not find alias or value \"" << name << "\"."
                                                         << " I'll tell you the ones I know about." << std::endl
-                                                        << GenValue::summary(), -1);
+                                                        << GenValue::summary());
         }
         return tv;
     }

+ 2 - 1
include/log.hpp

@@ -36,6 +36,7 @@
 #include <iostream>
 #include <fstream>
 #include <cstring>
+#include <csignal>
 #include <map>
 
 #include "config.hpp"
@@ -52,7 +53,7 @@ enum LogPriority {
     kLogDebug     = 0   // debug-level message
 };
 
-#define CRITICAL(x,y) std::clog << fv_util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; std::cout << "Errors encountered! See log file for details."<<std::endl;exit(y)
+#define CRITICAL(x) std::clog << fv_util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; std::cout << "Errors encountered! See log file for details."<<std::endl;raise(SIGTERM)
 #define ERROR(x) std::clog << fv_util::LogPriority::kLogError << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
 #define WARNING(x) std::clog << fv_util::LogPriority::kLogWarning << x << std::flush
 #define INFO(x) std::clog << fv_util::LogPriority::kLogInfo << x << std::flush

+ 2 - 2
root/include/root_container.hpp

@@ -104,8 +104,8 @@ namespace fv_root {
             auto hist_params = fv_util::the_config->get("hist-params");
             if (!hist_params[param_key]) {
                 CRITICAL("Key \"" << param_key
-                                  << "\" does not exist under hist-params in supplied config file. Add it!",
-                         true);
+                                  << "\" does not exist under hist-params in supplied config file. Add it!");
+                return THParams({"", 20, 0, 1, "", 20, 0, 1});
             } else {
                 auto params = hist_params[param_key];
                 return THParams({params["label_x"].as<std::string>(""),

+ 4 - 4
root/include/root_dataset.hpp

@@ -150,7 +150,7 @@ namespace fv_root {
         Value<T> *track_branch(const std::string &bname) {
             TBranch *branch = tree_obj->fChain->GetBranch(bname.c_str());
             if (branch == nullptr) {
-                CRITICAL("Branch: " << bname << " does not exist in input tree.", -1);
+                CRITICAL("Branch: " << bname << " does not exist in input tree.");
             }
             T *bref = (T *) branch->GetAddress();
             set_branch_status(bname, true);
@@ -164,7 +164,7 @@ namespace fv_root {
         Value<T *> *track_branch_ptr(const std::string &bname) {
             TBranch *branch = tree_obj->fChain->GetBranch(bname.c_str());
             if (branch == nullptr) {
-                CRITICAL("Branch: " << bname << " does not exist in input tree.", -1);
+                CRITICAL("Branch: " << bname << " does not exist in input tree.");
             }
             T *bref = (T *) branch->GetAddress();
             set_branch_status(bname, true);
@@ -180,7 +180,7 @@ namespace fv_root {
             if (!found) {
                 DataFileDescriptor &dfd = get_current_file();
                 CRITICAL("Branch: " << bname << " does not exist in input tree of file "
-                                    << dfd.filename, -1);
+                                    << dfd.filename);
             }
 
         }
@@ -189,7 +189,7 @@ namespace fv_root {
         Value<T> *track_branch_obj(const std::string &bname) {
             TBranch *branch = tree_obj->fChain->GetBranch(bname.c_str());
             if (branch == nullptr) {
-                CRITICAL("Branch: " << bname << " does not exist in input tree.", -1);
+                CRITICAL("Branch: " << bname << " does not exist in input tree.");
             }
             T **bref = (T **) branch->GetAddress();
             set_branch_status(bname, true);