diff --git a/src/shogun/kernel/Kernel.h b/src/shogun/kernel/Kernel.h index 88e66fb413b..4768cd9f3eb 100644 --- a/src/shogun/kernel/Kernel.h +++ b/src/shogun/kernel/Kernel.h @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff --git a/src/shogun/lib/Signal.cpp b/src/shogun/lib/Signal.cpp index 885c02096c8..3defa0fdd5c 100644 --- a/src/shogun/lib/Signal.cpp +++ b/src/shogun/lib/Signal.cpp @@ -8,21 +8,17 @@ * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society */ -#include - +#include #include -#include #include -#include #include #include using namespace shogun; using namespace rxcpp; -int CSignal::signals[NUMTRAPPEDSIGS]={SIGINT, SIGURG}; -struct sigaction CSignal::oldsigaction[NUMTRAPPEDSIGS]; +bool CSignal::m_active = false; rxcpp::connectable_observable CSignal::m_sigint_observable = rxcpp::observable<>::create([](rxcpp::subscriber s) { @@ -35,16 +31,7 @@ rxcpp::connectable_observable CSignal::m_sigurg_observable = }).publish(); CSignal::CSignal() -: CSGObject() { - // Set if the signal handler is active or not - m_active = true; -} - -CSignal::CSignal(bool active) : CSGObject() -{ - // Set if the signal handler is active or not - m_active = active; } CSignal::~CSignal() @@ -63,60 +50,37 @@ rxcpp::connectable_observable CSignal::get_SIGURG_observable() void CSignal::handler(int signal) { + /* If the handler is not enabled, then return */ + if (!m_active) + return; + if (signal == SIGINT) { - // SG_SPRINT("\nImmediately return to prompt / Prematurely finish - // computations / Do nothing (I/P/D)? ") - // char answer=fgetc(stdin); - /*switch (answer){ - case 'I': - m_sigint_observable.connect(); - break; - case 'P': - m_sigurg_observable.connect(); - break; - default: - SG_SPRINT("Continuing...\n") - break; - }*/ - SG_SPRINT("Killing the application...\n"); - m_sigint_observable.connect(); + SG_SPRINT( + "\n[ShogunSignalHandler] Immediately return to prompt / " + "Prematurely finish " + "computations / Do nothing (I/P/D)? ") + char answer = fgetc(stdin); + switch (answer) + { + case 'I': + SG_SPRINT("[ShogunSignalHandler] Killing the application...\n"); + m_sigint_observable.connect(); + exit(0); + break; + case 'P': + SG_SPRINT( + "[ShogunSignalHandler] Terminating" + " prematurely current algorithm...\n"); + m_sigurg_observable.connect(); + break; + default: + SG_SPRINT("[ShogunSignalHandler] Continuing...\n") + break; + } } - else if (signal == SIGURG) - m_sigurg_observable.connect(); else - SG_SPRINT("unknown signal %d received\n", signal) -} - -#if defined(__MINGW64__) || defined(_MSC_VER) || defined(__MINGW32__) -#define SIGBAD(signo) ( (signo) <=0 || (signo) >=NSIG) -Sigfunc *handlers[NSIG]={0}; - -int sigaddset(sigset_t *set, int signo) -{ - if (SIGBAD(signo)) { - errno = EINVAL; - return -1; - } - *set |= 1 << (signo-1); - return 0; -} - -int sigaction(int signo, const struct sigaction *act, struct sigaction *oact) -{ - if (SIGBAD(signo)) { - errno = EINVAL; - return -1; - } - - if(oact){ - oact->sa_handler = handlers[signo]; - oact->sa_mask = 0; - oact->sa_flags =0; + { + SG_SPRINT("[ShogunSignalHandler] Unknown signal %d received\n", signal) } - if (act) - handlers[signo]=act->sa_handler; - - return 0; } -#endif diff --git a/src/shogun/lib/Signal.h b/src/shogun/lib/Signal.h index 4b8aa46bcc9..cc4bfed8336 100644 --- a/src/shogun/lib/Signal.h +++ b/src/shogun/lib/Signal.h @@ -12,70 +12,23 @@ #define __SIGNAL__H_ #include -#include - -#if defined(__MINGW64__) || defined(_MSC_VER) -typedef unsigned long sigset_t; -#endif -#if defined(__MINGW32__) && !defined(__MINGW64__) -typedef int sigset_t; -#endif - -#ifndef SIGURG -#define SIGURG -16 -#endif - -#if defined(__MINGW64__) || defined(_MSC_VER) || defined(__MINGW32__) -typedef void Sigfunc (int); - -struct sigaction { - Sigfunc *sa_handler; - sigset_t sa_mask; - int sa_flags; -}; - -#define sigemptyset(ptr) (*(ptr) = 0) -#define sigfillset(ptr) ( *(ptr) = ~(sigset_t)0,0) - -int sigaddset(sigset_t*, int); -int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); -#endif - -#ifndef DISABLE_CANCEL_CALLBACK -namespace shogun -{ -extern void (*sg_cancel_computations)(bool &delayed, bool &immediately); -} -#endif - -#include #include -#include -#define NUMTRAPPEDSIGS 2 - namespace shogun { -/** @brief Class Signal implements signal handling to e.g. allow ctrl+c to cancel a - * long running process. - * - * This is done in two ways: - * - * -# A signal handler is attached to trap the SIGINT and SIGURG signal. - * Pressing ctrl+c or sending the SIGINT (kill ...) signal to the shogun - * process will make shogun print a message asking to immediately exit the - * running method and to fall back to the command line. - * -# When an URG signal is received or ctrl+c P is pressed shogun will - * prematurely stop a method and continue execution. For example when an SVM - * solver takes a long time without progressing much, one might still be - * interested in the result and should thus send SIGURG or interactively - * prematurely stop the method - */ -class CSignal : public CSGObject -{ + /** @brief Class Signal implements signal handling to e.g. allow CTRL+C to + * cancel a long running process. + * + * -# A signal handler is attached to trap the SIGINT signal. + * Pressing CTRL+C or sending the SIGINT (kill ...) signal to the shogun + * process will make shogun print a message asking the user to choose an + * option bewteen: immediately exit the running method and fall back to + * the command line, prematurely stop the current algoritmh and do nothing. + */ + class CSignal : public CSGObject + { public: CSignal(); - CSignal(bool active); virtual ~CSignal(); /** Signal handler. Need to be registered with std::signal. @@ -96,7 +49,7 @@ class CSignal : public CSGObject */ rxcpp::connectable_observable get_SIGURG_observable(); - /** cancel computations + /** Cancel computations * * @return if computations should be cancelled */ @@ -105,20 +58,24 @@ class CSignal : public CSGObject return false; } + /** Enable signal handler + */ + void enable_handler() + { + m_active = true; + } + /** @return object name */ virtual const char* get_name() const { return "Signal"; } private: - /** signals; handling external lib */ - static int signals[NUMTRAPPEDSIGS]; - - /** signal actions */ - static struct sigaction oldsigaction[NUMTRAPPEDSIGS]; - - /** active signal */ - bool m_active; + /** Active signal */ + static bool m_active; + /** SIGINT Observable */ static rxcpp::connectable_observable m_sigint_observable; + + /** SIGURG Observable */ static rxcpp::connectable_observable m_sigurg_observable; }; } diff --git a/tests/unit/lib/Signal_unittest.cc b/tests/unit/lib/Signal_unittest.cc index 9558b683c38..fa30880e1f7 100644 --- a/tests/unit/lib/Signal_unittest.cc +++ b/tests/unit/lib/Signal_unittest.cc @@ -9,33 +9,32 @@ using namespace rxcpp; TEST(Signal, SIGINT_test) { - CSignal tmp; + tmp.enable_handler(); int on_next_v = 0; int on_complete_v = 0; auto sub = rxcpp::make_subscriber( [&on_next_v](int v) { on_next_v = 1; }, [&]() { on_complete_v = 1; }); tmp.get_SIGINT_observable().subscribe(sub); + tmp.get_SIGINT_observable().connect(); - tmp.handler(SIGINT); - - EXPECT_TRUE(on_next_v == 0); EXPECT_TRUE(on_complete_v == 1); + EXPECT_TRUE(on_next_v == 0); } TEST(Signal, SIGURG_test) { CSignal tmp; + tmp.enable_handler(); int on_next_v = 0; int on_complete_v = 0; auto sub = rxcpp::make_subscriber( [&](int v) { on_next_v++; }, [&]() { on_complete_v++; }); tmp.get_SIGURG_observable().subscribe(sub); - - tmp.handler(SIGURG); + tmp.get_SIGURG_observable().connect(); EXPECT_TRUE(on_next_v == 1); EXPECT_TRUE(on_complete_v == 0);