Skip to content

Commit

Permalink
[PrematureStopping] Removed Windows code and polish code.
Browse files Browse the repository at this point in the history
  • Loading branch information
geektoni authored and vigsterkr committed Jul 12, 2017
1 parent 0b9aeaa commit 0a742a2
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 140 deletions.
1 change: 0 additions & 1 deletion src/shogun/kernel/Kernel.h
Expand Up @@ -18,7 +18,6 @@
#include <shogun/lib/config.h>

#include <shogun/lib/common.h>
#include <shogun/lib/Signal.h>
#include <shogun/io/SGIO.h>
#include <shogun/io/File.h>
#include <shogun/mathematics/Math.h>
Expand Down
96 changes: 30 additions & 66 deletions src/shogun/lib/Signal.cpp
Expand Up @@ -8,21 +8,17 @@
* Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
*/

#include <shogun/lib/config.h>

#include <csignal>
#include <stdlib.h>

#include <rxcpp/rx-includes.hpp>
#include <rxcpp/rx.hpp>
#include <shogun/base/init.h>
#include <shogun/io/SGIO.h>
#include <shogun/lib/Signal.h>

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<int> CSignal::m_sigint_observable =
rxcpp::observable<>::create<int>([](rxcpp::subscriber<int> s) {
Expand All @@ -35,16 +31,7 @@ rxcpp::connectable_observable<int> 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()
Expand All @@ -63,60 +50,37 @@ rxcpp::connectable_observable<int> 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
91 changes: 24 additions & 67 deletions src/shogun/lib/Signal.h
Expand Up @@ -12,70 +12,23 @@
#define __SIGNAL__H_

#include <rxcpp/rx-includes.hpp>
#include <shogun/lib/config.h>

#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 <shogun/lib/ShogunException.h>
#include <shogun/base/SGObject.h>

#include <csignal>
#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.
Expand All @@ -96,7 +49,7 @@ class CSignal : public CSGObject
*/
rxcpp::connectable_observable<int> get_SIGURG_observable();

/** cancel computations
/** Cancel computations
*
* @return if computations should be cancelled
*/
Expand All @@ -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<int> m_sigint_observable;

/** SIGURG Observable */
static rxcpp::connectable_observable<int> m_sigurg_observable;
};
}
Expand Down
11 changes: 5 additions & 6 deletions tests/unit/lib/Signal_unittest.cc
Expand Up @@ -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<int>(
[&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>(
[&](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);
Expand Down

0 comments on commit 0a742a2

Please sign in to comment.