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-2018 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file interrupt.c
17  * @brief methods and datastructures for catching the user CTRL-C interrupt
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <sys/types.h>
25 #include <stdlib.h>
26 #include <signal.h>
27 
28 #include "scip/def.h"
29 #include "blockmemshell/memory.h"
30 #include "scip/interrupt.h"
31 
32 
33 static volatile
34 int ninterrupts = 0; /**< static variable counting the number of CTRL-C interrupts */
35 
36 
37 #ifdef NO_SIGACTION
38 typedef void (*SigHdlr)(int);
39 
40 /** CTRL-C interrupt data */
41 struct SCIP_Interrupt
42 {
43  SigHdlr oldsighdlr; /**< old CTRL-C interrupt handler */
44  int nuses; /**< number of times, the interrupt is captured */
45 };
46 
47 #else
48 
49 /** CTRL-C interrupt data */
51 {
52  struct sigaction oldsigaction; /**< old CTRL-C interrupt handler */
53  int nuses; /**< number of times, the interrupt is captured */
54 };
55 #endif
56 
57 /** interrupt handler for CTRL-C interrupts */
58 static
60  int signum /**< interrupt signal number */
61  )
62 { /*lint --e{715}*/
63  ninterrupts++;
64  if( ninterrupts >= 5 )
65  {
66  printf("pressed CTRL-C %d times. forcing termination.\n", ninterrupts);
67  exit(1);
68  }
69  else
70  {
71  printf("pressed CTRL-C %d times (5 times for forcing termination)\n", ninterrupts);
72  }
73 }
74 
75 /** creates a CTRL-C interrupt data */
77  SCIP_INTERRUPT** interrupt /**< pointer to store the CTRL-C interrupt data */
78  )
79 {
80  assert(interrupt != NULL);
81 
82  SCIP_ALLOC( BMSallocMemory(interrupt) );
83  (*interrupt)->nuses = 0;
84 
85  return SCIP_OKAY;
86 }
87 
88 /** frees a CTRL-C interrupt data */
90  SCIP_INTERRUPT** interrupt /**< pointer to the CTRL-C interrupt data */
91  )
92 {
93  assert(interrupt != NULL);
94 
95  BMSfreeMemory(interrupt);
96 }
97 
98 /** captures the CTRL-C interrupt to call the SCIP's own interrupt handler */
100  SCIP_INTERRUPT* interrupt /**< CTRL-C interrupt data */
101  )
102 {
103  assert(interrupt != NULL);
104  assert(interrupt->nuses >= 0);
105 
106  if( interrupt->nuses == 0 )
107  {
108 #ifdef NO_SIGACTION
109  interrupt->oldsighdlr = signal(SIGINT, interruptHandler);
110 #else
111  struct sigaction newaction;
112 
113  /* initialize new signal action */
114  newaction.sa_handler = interruptHandler;
115  newaction.sa_flags = 0;
116  (void)sigemptyset(&newaction.sa_mask);
117 
118  /* set new signal action, and remember old one */
119  (void)sigaction(SIGINT, &newaction, &interrupt->oldsigaction);
120 #endif
121 
122  ninterrupts = 0;
123  }
124  interrupt->nuses++;
125 }
126 
127 /** releases the CTRL-C interrupt and restores the old interrupt handler */
129  SCIP_INTERRUPT* interrupt /**< CTRL-C interrupt data */
130  )
131 {
132  assert(interrupt != NULL);
133  assert(interrupt->nuses >= 1);
134 
135  interrupt->nuses--;
136  if( interrupt->nuses == 0 )
137  {
138 #ifdef NO_SIGACTION
139  (void)signal(SIGINT, interrupt->oldsighdlr);
140 #else
141  (void)sigaction(SIGINT, &interrupt->oldsigaction, NULL);
142 #endif
143  }
144 }
145 
146 /** returns whether the user interrupted by pressing CTRL-C */
148  void
149  )
150 {
151  return (ninterrupts > 0);
152 }
153 
154 /** resets the number of interrupts to 0 */
156  void
157  )
158 {
159  ninterrupts = 0;
160 }
161 
void SCIPinterruptCapture(SCIP_INTERRUPT *interrupt)
Definition: interrupt.c:99
void SCIPresetInterrupted(void)
Definition: interrupt.c:155
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
static void interruptHandler(int signum)
Definition: interrupt.c:59
SCIP_RETCODE SCIPinterruptCreate(SCIP_INTERRUPT **interrupt)
Definition: interrupt.c:76
#define BMSfreeMemory(ptr)
Definition: memory.h:127
void SCIPinterruptRelease(SCIP_INTERRUPT *interrupt)
Definition: interrupt.c:128
methods for catching the user CTRL-C interrupt
#define SCIP_Bool
Definition: def.h:61
SCIP_Bool SCIPinterrupted(void)
Definition: interrupt.c:147
struct sigaction oldsigaction
Definition: interrupt.c:52
void SCIPinterruptFree(SCIP_INTERRUPT **interrupt)
Definition: interrupt.c:89
static volatile int ninterrupts
Definition: interrupt.c:34
#define BMSallocMemory(ptr)
Definition: memory.h:101
common defines and data types used in all packages of SCIP
#define SCIP_ALLOC(x)
Definition: def.h:361
memory allocation routines