Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sigaction and porting Linux code to Windows

I am trying to port caffe (developed for Linux) source code to Windows environment. The problem is at sigaction structure at signal_handler.cpp and signal_handler.h. The source codes are shown below. My query is which library or code replacement can be done to make this sigaction works in Windows.

///Header file

#ifndef INCLUDE_CAFFE_UTIL_SIGNAL_HANDLER_H_
#define INCLUDE_CAFFE_UTIL_SIGNAL_HANDLER_H_

#include "caffe/proto/caffe.pb.h"
#include "caffe/solver.hpp"

namespace caffe {

class SignalHandler {
 public:
  // Contructor. Specify what action to take when a signal is received.
  SignalHandler(SolverAction::Enum SIGINT_action,
                SolverAction::Enum SIGHUP_action);
  ~SignalHandler();
  ActionCallback GetActionFunction();
 private:
  SolverAction::Enum CheckForSignals() const;
  SolverAction::Enum SIGINT_action_;
  SolverAction::Enum SIGHUP_action_;
};

}  // namespace caffe

#endif  // INCLUDE_CAFFE_UTIL_SIGNAL_HANDLER_H_

///Source file

    #include <boost/bind.hpp>
    #include <glog/logging.h>

    #include <signal.h>
    #include <csignal>

    #include "caffe/util/signal_handler.h"

    namespace {
      static volatile sig_atomic_t got_sigint = false;
      static volatile sig_atomic_t got_sighup = false;
      static bool already_hooked_up = false;

      void handle_signal(int signal) {
        switch (signal) {
        case SIGHUP:
          got_sighup = true;
          break;
        case SIGINT:
          got_sigint = true;
          break;
        }
      }

      void HookupHandler() {
        if (already_hooked_up) {
          LOG(FATAL) << "Tried to hookup signal handlers more than once.";
        }
        already_hooked_up = true;

        struct sigaction sa;
        // Setup the handler
        sa.sa_handler = &handle_signal;
        // Restart the system call, if at all possible
        sa.sa_flags = SA_RESTART;
        // Block every signal during the handler
        sigfillset(&sa.sa_mask);
        // Intercept SIGHUP and SIGINT
        if (sigaction(SIGHUP, &sa, NULL) == -1) {
          LOG(FATAL) << "Cannot install SIGHUP handler.";
        }
        if (sigaction(SIGINT, &sa, NULL) == -1) {
          LOG(FATAL) << "Cannot install SIGINT handler.";
        }
      }

      // Set the signal handlers to the default.
      void UnhookHandler() {
        if (already_hooked_up) {
          struct sigaction sa;
          // Setup the sighub handler
          sa.sa_handler = SIG_DFL;
          // Restart the system call, if at all possible
          sa.sa_flags = SA_RESTART;
          // Block every signal during the handler
          sigfillset(&sa.sa_mask);
          // Intercept SIGHUP and SIGINT
          if (sigaction(SIGHUP, &sa, NULL) == -1) {
            LOG(FATAL) << "Cannot uninstall SIGHUP handler.";
          }
          if (sigaction(SIGINT, &sa, NULL) == -1) {
            LOG(FATAL) << "Cannot uninstall SIGINT handler.";
          }

          already_hooked_up = false;
        }
      }

      // Return true iff a SIGINT has been received since the last time this
      // function was called.
      bool GotSIGINT() {
        bool result = got_sigint;
        got_sigint = false;
        return result;
      }

      // Return true iff a SIGHUP has been received since the last time this
      // function was called.
      bool GotSIGHUP() {
        bool result = got_sighup;
        got_sighup = false;
        return result;
      }
    }  // namespace

    namespace caffe {

    SignalHandler::SignalHandler(SolverAction::Enum SIGINT_action,
                                 SolverAction::Enum SIGHUP_action):
      SIGINT_action_(SIGINT_action),
      SIGHUP_action_(SIGHUP_action) {
      HookupHandler();
    }

    SignalHandler::~SignalHandler() {
      UnhookHandler();
    }

    SolverAction::Enum SignalHandler::CheckForSignals() const {
      if (GotSIGHUP()) {
        return SIGHUP_action_;
      }
      if (GotSIGINT()) {
        return SIGINT_action_;
      }
      return SolverAction::NONE;
    }

    // Return the function that the solver can use to find out if a snapshot or
    // early exit is being requested.
    ActionCallback SignalHandler::GetActionFunction() {
      return boost::bind(&SignalHandler::CheckForSignals, this);
    }

    }  // namespace caffe

The errors are

.\src\caffe\util\signal_handler.cpp(39): error C2065: 'SIGHUP' : undeclared identifier
1>..\src\caffe\util\signal_handler.cpp(42): error C2514: '`anonymous-namespace'::HookupHandler::sigaction' : class has no constructors
1>          ..\src\caffe\util\signal_handler.cpp(31) : see declaration of '`anonymous-namespace'::HookupHandler::sigaction'
1>..\src\caffe\util\signal_handler.cpp(50): error C2079: 'sa' uses undefined struct '`anonymous-namespace'::UnhookHandler::sigaction'
1>..\src\caffe\util\signal_handler.cpp(52): error C2228: left of '.sa_handler' must have class/struct/union
1>          type is 'int'
1>..\src\caffe\util\signal_handler.cpp(54): error C2228: left of '.sa_flags' must have class/struct/union
1>          type is 'int'
1>..\src\caffe\util\signal_handler.cpp(54): error C2065: 'SA_RESTART' : undeclared identifier
1>..\src\caffe\util\signal_handler.cpp(56): error C2228: left of '.sa_mask' must have class/struct/union
like image 657
batuman Avatar asked Sep 04 '15 04:09

batuman


1 Answers

sigaction is part of the UNIX signals API. Windows provides only signal, which doesn't support SIGHUP or any flags (such as SA_RESTART). However, the very basic support is still there, so the code should still work reasonably correctly if you use just signal (and not sigaction).

like image 98
nneonneo Avatar answered Oct 24 '22 04:10

nneonneo