////////////////////////////////////////////////////////////////////////////////
// 
// Signal.hh 
//
//    produced: 2024-04-11 jr
//
////////////////////////////////////////////////////////////////////////////////
#ifndef SIGNAL_HH
#define SIGNAL_HH

#include <iostream>

#include <signal.h>
#include "CommandlineOptions.hh"

extern "C" void topcom_signalhandler(int signalno);

namespace topcom {

  class Signal {
  private:
    static constexpr int            _maxrepeat = 3;
    static volatile  sig_atomic_t   _signalno;
    static volatile  sig_atomic_t   _repeatcounter;
    static struct    sigaction      _sigaction;
    static struct    sigaction      _INTsigaction;
    static struct    sigaction      _TERMsigaction;
  public:
    inline static void signalhandler(int signalno) {
      _signalno = signalno;
      ++_repeatcounter;
      if ((_signalno == SIGINT) && (_repeatcounter > _maxrepeat)) {
	sigaction(SIGINT, &_INTsigaction, NULL);
	raise(SIGINT);
      }
      if ((_signalno = SIGTERM) && (_repeatcounter > _maxrepeat)) {
	sigaction(SIGTERM, &_TERMsigaction, NULL);
	raise(SIGTERM);
      }
    }

    inline static void init() {
      MessageStreams::verbose() << "initializing signal handling" << std::endl;
      _sigaction.sa_handler = &topcom_signalhandler;
      sigaction(SIGINT, &_sigaction, &_INTsigaction);
      sigaction(SIGTERM, &_sigaction, &_TERMsigaction);
    }

    inline static bool signal_received() {
      return _signalno != 0;
    }

    inline static sig_atomic_t signalno() {
      return _signalno;
    }

    inline static int exit_value() {
      if (_signalno != 0) {
	return _signalno + 128;
      }
      else {
	return 0;
      }
    }
  };

}; // namespace topcom



#endif

// eof Signal.hh
