Scippy

SCIP

Solving Constraint Integer Programs

interrupt.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file interrupt.c
26  * @ingroup OTHER_CFILES
27  * @brief methods and datastructures for catching the user CTRL-C interrupt
28  * @author Tobias Achterberg
29  */
30 
31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32 
33 #include <assert.h>
34 #include <sys/types.h>
35 #include <stdlib.h>
36 #include <signal.h>
37 
38 #include "scip/def.h"
39 #include "scip/pub_message.h"
40 #include "blockmemshell/memory.h"
41 #include "scip/interrupt.h"
42 
43 
44 static volatile
45 int ninterrupts = 0; /**< static variable counting the number of CTRL-C interrupts */
46 static volatile
47 int nterms = 0; /**< static variable counting the number of times that the process received a SIGTERM signal */
48 
49 
50 #ifdef SCIP_NO_SIGACTION
51 typedef void (*SigHdlr)(int);
52 
53 /** CTRL-C interrupt data */
54 struct SCIP_Interrupt
55 {
56  SigHdlr oldsighdlr; /**< old CTRL-C interrupt handler */
57  int nuses; /**< number of times, the interrupt is captured */
58 };
59 
60 #else
61 
62 /** CTRL-C interrupt data */
64 {
65  struct sigaction oldsigaction; /**< old CTRL-C interrupt handler */
66  int nuses; /**< number of times, the interrupt is captured */
67 };
68 #endif
69 
70 /** interrupt handler for CTRL-C interrupts */
71 static
73  int signum /**< interrupt signal number */
74  )
75 {
76  SCIP_UNUSED(signum);
77 
78  ninterrupts++;
79  if( ninterrupts >= 5 )
80  {
81  printf("pressed CTRL-C %d times. forcing termination.\n", ninterrupts);
82  exit(1);
83  }
84  else
85  {
86  printf("pressed CTRL-C %d times (5 times for forcing termination)\n", ninterrupts);
87  }
88 }
89 
90 /** creates a CTRL-C interrupt data */
92  SCIP_INTERRUPT** interrupt /**< pointer to store the CTRL-C interrupt data */
93  )
94 {
95  assert(interrupt != NULL);
96 
97  SCIP_ALLOC( BMSallocMemory(interrupt) );
98  (*interrupt)->nuses = 0;
99 
100  return SCIP_OKAY;
101 }
102 
103 /** frees a CTRL-C interrupt data */
105  SCIP_INTERRUPT** interrupt /**< pointer to the CTRL-C interrupt data */
106  )
107 {
108  assert(interrupt != NULL);
109 
110  BMSfreeMemory(interrupt);
111 }
112 
113 /** captures the CTRL-C interrupt to call the SCIP's own interrupt handler */
115  SCIP_INTERRUPT* interrupt /**< CTRL-C interrupt data */
116  )
117 {
118  assert(interrupt != NULL);
119  assert(interrupt->nuses >= 0);
120 
121  if( interrupt->nuses == 0 )
122  {
123 #ifdef SCIP_NO_SIGACTION
124  interrupt->oldsighdlr = signal(SIGINT, interruptHandler);
125 #else
126  struct sigaction newaction;
127 
128  /* initialize new signal action */
129  newaction.sa_handler = interruptHandler;
130  newaction.sa_flags = 0;
131  (void)sigemptyset(&newaction.sa_mask);
132 
133  /* set new signal action, and remember old one */
134  (void)sigaction(SIGINT, &newaction, &interrupt->oldsigaction);
135 #endif
136 
137  ninterrupts = 0;
138  nterms = 0;
139  }
140  interrupt->nuses++;
141 }
142 
143 /** releases the CTRL-C interrupt and restores the old interrupt handler */
145  SCIP_INTERRUPT* interrupt /**< CTRL-C interrupt data */
146  )
147 {
148  assert(interrupt != NULL);
149  assert(interrupt->nuses >= 1);
150 
151  interrupt->nuses--;
152  if( interrupt->nuses == 0 )
153  {
154 #ifdef SCIP_NO_SIGACTION
155  (void)signal(SIGINT, interrupt->oldsighdlr);
156 #else
157  (void)sigaction(SIGINT, &interrupt->oldsigaction, NULL);
158 #endif
159  }
160 }
161 
162 /** returns whether the user interrupted by pressing CTRL-C */
164  void
165  )
166 {
167  return (ninterrupts > 0);
168 }
169 
170 /** returns whether a process termination signal was received */
172  void
173  )
174 {
175  return (nterms > 0);
176 }
177 
178 /** sends a termination signal to all SCIP processes so that they try to terminate as soon as possible
179  *
180  * @note For terminating a specific SCIP process use SCIPinterruptSolve().
181  */
183  void
184  )
185 {
186  nterms++;
187 }
188 
189 /** resets the number of interrupts to 0 */
191  void
192  )
193 {
194  ninterrupts = 0;
195  nterms = 0;
196 }
197 
static volatile int nterms
Definition: interrupt.c:47
void SCIPinterruptCapture(SCIP_INTERRUPT *interrupt)
Definition: interrupt.c:114
void SCIPresetInterrupted(void)
Definition: interrupt.c:190
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
#define SCIP_UNUSED(x)
Definition: def.h:448
static void interruptHandler(int signum)
Definition: interrupt.c:72
SCIP_RETCODE SCIPinterruptCreate(SCIP_INTERRUPT **interrupt)
Definition: interrupt.c:91
#define BMSfreeMemory(ptr)
Definition: memory.h:147
SCIP_Bool SCIPterminated(void)
Definition: interrupt.c:171
void SCIPinterruptRelease(SCIP_INTERRUPT *interrupt)
Definition: interrupt.c:144
#define NULL
Definition: lpi_spx1.cpp:164
methods for catching the user CTRL-C interrupt
#define SCIP_Bool
Definition: def.h:93
SCIP_Bool SCIPinterrupted(void)
Definition: interrupt.c:163
struct sigaction oldsigaction
Definition: interrupt.c:65
void SCIPinterruptFree(SCIP_INTERRUPT **interrupt)
Definition: interrupt.c:104
public methods for message output
static volatile int ninterrupts
Definition: interrupt.c:45
#define BMSallocMemory(ptr)
Definition: memory.h:120
common defines and data types used in all packages of SCIP
void SCIPtryTerminate(void)
Definition: interrupt.c:182
#define SCIP_ALLOC(x)
Definition: def.h:405
memory allocation routines