SHOGUN  6.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Signal.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  */
10 
11 #include <shogun/lib/config.h>
12 
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include <shogun/io/SGIO.h>
17 #include <shogun/lib/Signal.h>
18 #include <shogun/base/init.h>
19 
20 using namespace shogun;
21 
23 struct sigaction CSignal::oldsigaction[NUMTRAPPEDSIGS];
24 bool CSignal::active=false;
27 
29 : CSGObject()
30 {
31 }
32 
34 {
35  if (!unset_handler())
36  SG_PRINT("error uninitalizing signal handler\n")
37 }
38 
39 void CSignal::handler(int signal)
40 {
41  if (signal == SIGINT)
42  {
43  SG_SPRINT("\nImmediately return to prompt / Prematurely finish computations / Do nothing (I/P/D)? ")
44  char answer=fgetc(stdin);
45 
46  if (answer == 'I')
47  {
48  unset_handler();
49  set_cancel(true);
50  if (sg_print_error)
51  sg_print_error(stdout, "sg stopped by SIGINT\n");
52  }
53  else if (answer == 'P')
54  set_cancel();
55  else
56  SG_SPRINT("Continuing...\n")
57  }
58  else if (signal == SIGURG)
59  set_cancel();
60  else
61  SG_SPRINT("unknown signal %d received\n", signal)
62 }
63 
65 {
66  if (!active)
67  {
68  struct sigaction act;
69  sigset_t st;
70 
71  sigemptyset(&st);
72  for (int32_t i=0; i<NUMTRAPPEDSIGS; i++)
73  sigaddset(&st, signals[i]);
74 
75 #if !(defined(__INTERIX) || defined(__MINGW64__) || defined(_MSC_VER) || defined(__MINGW32__))
76  act.sa_sigaction=NULL; //just in case
77 #endif
78  act.sa_handler=CSignal::handler;
79  act.sa_mask = st;
80  act.sa_flags = 0;
81 
82  for (int32_t i=0; i<NUMTRAPPEDSIGS; i++)
83  {
84  if (sigaction(signals[i], &act, &oldsigaction[i]))
85  {
86  SG_SPRINT("Error trapping signals!\n")
87  for (int32_t j=i-1; j>=0; j--)
88  sigaction(signals[i], &oldsigaction[i], NULL);
89 
90  clear();
91  return false;
92  }
93  }
94 
95  active=true;
96  return true;
97  }
98  else
99  return false;
100 }
101 
103 {
104  if (active)
105  {
106  bool result=true;
107 
108  for (int32_t i=0; i<NUMTRAPPEDSIGS; i++)
109  {
110  if (sigaction(signals[i], &oldsigaction[i], NULL))
111  {
112  SG_SPRINT("error uninitalizing signal handler for signal %d\n", signals[i])
113  result=false;
114  }
115  }
116 
117  if (result)
118  clear();
119 
120  return result;
121  }
122  else
123  return false;
124 }
125 
127 {
128  cancel_computation=false;
129  cancel_immediately=false;
130 }
131 
132 void CSignal::set_cancel(bool immediately)
133 {
134  cancel_computation=true;
135 
136  if (immediately)
137  cancel_immediately=true;
138 }
139 
141 {
142  clear_cancel();
143  active=false;
144  memset(&CSignal::oldsigaction, 0, sizeof(CSignal::oldsigaction));
145 }
146 
147 #if defined(__MINGW64__) || defined(_MSC_VER) || defined(__MINGW32__)
148 #define SIGBAD(signo) ( (signo) <=0 || (signo) >=NSIG)
149 Sigfunc *handlers[NSIG]={0};
150 
151 int sigaddset(sigset_t *set, int signo)
152 {
153  if (SIGBAD(signo)) {
154  errno = EINVAL;
155  return -1;
156  }
157  *set |= 1 << (signo-1);
158  return 0;
159 }
160 
161 int sigaction(int signo, const struct sigaction *act, struct sigaction *oact)
162 {
163  if (SIGBAD(signo)) {
164  errno = EINVAL;
165  return -1;
166  }
167 
168  if(oact){
169  oact->sa_handler = handlers[signo];
170  oact->sa_mask = 0;
171  oact->sa_flags =0;
172  }
173  if (act)
174  handlers[signo]=act->sa_handler;
175 
176  return 0;
177 }
178 #endif
static bool set_handler()
Definition: Signal.cpp:64
#define SIGURG
Definition: Signal.h:24
static bool active
Definition: Signal.h:134
#define SG_PRINT(...)
Definition: SGIO.h:136
#define SG_SPRINT(...)
Definition: SGIO.h:179
void(* sg_print_error)(FILE *target, const char *str)
function called to print error messages
Definition: init.cpp:51
Class SGObject is the base class of all shogun objects.
Definition: SGObject.h:125
static bool cancel_computation
Definition: Signal.h:137
static void clear_cancel()
Definition: Signal.cpp:126
static bool unset_handler()
Definition: Signal.cpp:102
#define NUMTRAPPEDSIGS
Definition: Signal.h:54
static void handler(int signal)
Definition: Signal.cpp:39
static int signals[NUMTRAPPEDSIGS]
Definition: Signal.h:128
static void clear()
Definition: Signal.cpp:140
virtual ~CSignal()
Definition: Signal.cpp:33
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
Class Signal implements signal handling to e.g. allow ctrl+c to cancel a long running process...
Definition: Signal.h:73
static struct sigaction oldsigaction[NUMTRAPPEDSIGS]
Definition: Signal.h:131
static void set_cancel(bool immediately=false)
Definition: Signal.cpp:132
static bool cancel_immediately
Definition: Signal.h:140

SHOGUN Machine Learning Toolbox - Documentation