SHOGUN
v3.2.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 1999-2009 Soeren Sonnenburg 00008 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 */ 00010 00011 #include <shogun/lib/config.h> 00012 00013 #ifndef WIN32 00014 00015 #include <stdlib.h> 00016 #include <signal.h> 00017 #include <string.h> 00018 00019 #include <shogun/io/SGIO.h> 00020 #include <shogun/lib/Signal.h> 00021 00022 using namespace shogun; 00023 00024 int CSignal::signals[NUMTRAPPEDSIGS]={SIGINT, SIGURG}; 00025 struct sigaction CSignal::oldsigaction[NUMTRAPPEDSIGS]; 00026 bool CSignal::active=false; 00027 bool CSignal::cancel_computation=false; 00028 bool CSignal::cancel_immediately=false; 00029 00030 CSignal::CSignal() 00031 : CSGObject() 00032 { 00033 } 00034 00035 CSignal::~CSignal() 00036 { 00037 if (!unset_handler()) 00038 SG_PRINT("error uninitalizing signal handler\n") 00039 } 00040 00041 void CSignal::handler(int signal) 00042 { 00043 if (signal == SIGINT) 00044 { 00045 SG_SPRINT("\nImmediately return to prompt / Prematurely finish computations / Do nothing (I/P/D)? ") 00046 char answer=fgetc(stdin); 00047 00048 if (answer == 'I') 00049 { 00050 unset_handler(); 00051 set_cancel(true); 00052 if (sg_print_error) 00053 sg_print_error(stdout, "sg stopped by SIGINT\n"); 00054 } 00055 else if (answer == 'P') 00056 set_cancel(); 00057 else 00058 SG_SPRINT("Continuing...\n") 00059 } 00060 else if (signal == SIGURG) 00061 set_cancel(); 00062 else 00063 SG_SPRINT("unknown signal %d received\n", signal) 00064 } 00065 00066 bool CSignal::set_handler() 00067 { 00068 if (!active) 00069 { 00070 struct sigaction act; 00071 sigset_t st; 00072 00073 sigemptyset(&st); 00074 for (int32_t i=0; i<NUMTRAPPEDSIGS; i++) 00075 sigaddset(&st, signals[i]); 00076 00077 #ifndef __INTERIX 00078 act.sa_sigaction=NULL; //just in case 00079 #endif 00080 act.sa_handler=CSignal::handler; 00081 act.sa_mask = st; 00082 act.sa_flags = 0; 00083 00084 for (int32_t i=0; i<NUMTRAPPEDSIGS; i++) 00085 { 00086 if (sigaction(signals[i], &act, &oldsigaction[i])) 00087 { 00088 SG_SPRINT("Error trapping signals!\n") 00089 for (int32_t j=i-1; j>=0; j--) 00090 sigaction(signals[i], &oldsigaction[i], NULL); 00091 00092 clear(); 00093 return false; 00094 } 00095 } 00096 00097 active=true; 00098 return true; 00099 } 00100 else 00101 return false; 00102 } 00103 00104 bool CSignal::unset_handler() 00105 { 00106 if (active) 00107 { 00108 bool result=true; 00109 00110 for (int32_t i=0; i<NUMTRAPPEDSIGS; i++) 00111 { 00112 if (sigaction(signals[i], &oldsigaction[i], NULL)) 00113 { 00114 SG_SPRINT("error uninitalizing signal handler for signal %d\n", signals[i]) 00115 result=false; 00116 } 00117 } 00118 00119 if (result) 00120 clear(); 00121 00122 return result; 00123 } 00124 else 00125 return false; 00126 } 00127 00128 void CSignal::clear_cancel() 00129 { 00130 cancel_computation=false; 00131 cancel_immediately=false; 00132 } 00133 00134 void CSignal::set_cancel(bool immediately) 00135 { 00136 cancel_computation=true; 00137 00138 if (immediately) 00139 cancel_immediately=true; 00140 } 00141 00142 void CSignal::clear() 00143 { 00144 clear_cancel(); 00145 active=false; 00146 memset(&CSignal::oldsigaction, 0, sizeof(CSignal::oldsigaction)); 00147 } 00148 #endif //WIN32