Sigaction и портирование кода Linux на Windows

Я пытаюсь портировать кофейная (разработано для Linux) исходный код для среды Windows. Проблема в sigaction структура в signal_handler.cpp а также signal_handler.h, Исходные коды приведены ниже.
Мой запрос, какая библиотека или замена кода может быть сделано, чтобы сделать это sigaction работает в винде.

/// Заголовочный файл

#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_

///Исходный файл

    #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

Ошибки

.\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

7

Решение

sigaction является частью API сигналов UNIX. Windows предоставляет только signal, который не поддерживает SIGHUP или любые флаги (такие как SA_RESTART). Тем не менее, базовая поддержка все еще существует, поэтому код должен работать достаточно корректно, если вы используете только signal (и не sigaction).

7

Другие решения

Основано на @nneonneo:

void handle_signal(int signal) {
switch (signal) {
#ifdef _WIN32
case SIGTERM:
case SIGABRT:
case SIGBREAK:
#else
case SIGHUP:
#endif
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;
#ifdef _WIN32
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
signal(SIGABRT, handle_signal);
#else
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.";
}
#endif
}
void UnhookHandler() {
if (already_hooked_up) {
#ifdef _WIN32
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGABRT, SIG_DFL);
#else
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.";
}
#endif

already_hooked_up = false;
}
}
5

По вопросам рекламы [email protected]