@@ -34,7 +34,6 @@ Interrupt and signal handling for Cython
34
34
#include <stdlib.h>
35
35
#include <limits.h>
36
36
#include <errno.h>
37
- #include <pthread.h>
38
37
#if HAVE_SYS_TYPES_H
39
38
#include <sys/types.h>
40
39
#endif
@@ -88,6 +87,9 @@ void custom_set_pending_signal(int sig){
88
87
#if HAVE_WINDOWS_H
89
88
#include <windows.h>
90
89
#endif
90
+ #if !_WIN32
91
+ #include <pthread.h>
92
+ #endif
91
93
#include "struct_signals.h"
92
94
93
95
@@ -108,9 +110,11 @@ static sigset_t default_sigmask;
108
110
static sigset_t sigmask_with_sigint ;
109
111
#endif
110
112
113
+ #if !_WIN32
111
114
/* A trampoline to jump to after handling a signal. */
112
115
static cyjmp_buf trampoline_setup ;
113
116
static sigjmp_buf trampoline ;
117
+ #endif
114
118
115
119
static void setup_cysignals_handlers (void );
116
120
static void cysigs_interrupt_handler (int sig );
@@ -194,15 +198,23 @@ static inline void print_stderr_ptr(void *ptr)
194
198
195
199
/* Reset all signal handlers and the signal mask to their defaults. */
196
200
static inline void sig_reset_defaults (void ) {
201
+ #ifdef SIGHUP
197
202
signal (SIGHUP , SIG_DFL );
203
+ #endif
198
204
signal (SIGINT , SIG_DFL );
205
+ #ifdef SIGQUIT
199
206
signal (SIGQUIT , SIG_DFL );
207
+ #endif
200
208
signal (SIGILL , SIG_DFL );
201
209
signal (SIGABRT , SIG_DFL );
202
210
signal (SIGFPE , SIG_DFL );
211
+ #ifdef SIGBUS
203
212
signal (SIGBUS , SIG_DFL );
213
+ #endif
204
214
signal (SIGSEGV , SIG_DFL );
215
+ #ifdef SIGALRM
205
216
signal (SIGALRM , SIG_DFL );
217
+ #endif
206
218
signal (SIGTERM , SIG_DFL );
207
219
#if HAVE_SIGPROCMASK
208
220
sigprocmask (SIG_SETMASK , & default_sigmask , NULL );
@@ -228,10 +240,14 @@ static inline void sigdie_for_sig(int sig, int inside)
228
240
sigdie (sig , "Unhandled SIGFPE during signal handling." );
229
241
else if (sig == SIGSEGV )
230
242
sigdie (sig , "Unhandled SIGSEGV during signal handling." );
243
+ #ifdef SIGBUS
231
244
else if (sig == SIGBUS )
232
245
sigdie (sig , "Unhandled SIGBUS during signal handling." );
246
+ #endif
247
+ #ifdef SIGQUIT
233
248
else if (sig == SIGQUIT )
234
249
sigdie (sig , NULL );
250
+ #endif
235
251
else
236
252
sigdie (sig , "Unknown signal during signal handling." );
237
253
}
@@ -244,10 +260,14 @@ static inline void sigdie_for_sig(int sig, int inside)
244
260
sigdie (sig , "Unhandled SIGFPE: An unhandled floating point exception occurred." );
245
261
else if (sig == SIGSEGV )
246
262
sigdie (sig , "Unhandled SIGSEGV: A segmentation fault occurred." );
263
+ #ifdef SIGBUS
247
264
else if (sig == SIGBUS )
248
265
sigdie (sig , "Unhandled SIGBUS: A bus error occurred." );
266
+ #endif
267
+ #ifdef SIGQUIT
249
268
else if (sig == SIGQUIT )
250
269
sigdie (sig , NULL );
270
+ #endif
251
271
else
252
272
sigdie (sig , "Unknown signal received." );
253
273
}
@@ -330,8 +350,22 @@ static void cygwin_setup_alt_stack() {
330
350
331
351
#endif /* CYGWIN && __x86_64__ */
332
352
353
+ void get_monotonic_time (struct timespec * ts ) {
354
+ #ifdef _WIN32
355
+ LARGE_INTEGER frequency ;
356
+ LARGE_INTEGER counter ;
357
+
358
+ QueryPerformanceFrequency (& frequency );
359
+ QueryPerformanceCounter (& counter );
360
+
361
+ ts -> tv_sec = counter .QuadPart / frequency .QuadPart ;
362
+ ts -> tv_nsec = (counter .QuadPart % frequency .QuadPart ) * 1e9 / frequency .QuadPart ;
363
+ #else
364
+ clock_gettime (CLOCK_MONOTONIC , ts );
365
+ #endif
366
+ }
333
367
334
- /* Handler for SIGHUP, SIGINT, SIGALRM
368
+ /* Handler for SIGHUP, SIGINT, SIGALRM, SIGTERM
335
369
*
336
370
* Inside sig_on() (i.e. when cysigs.sig_on_count is positive), this
337
371
* raises an exception and jumps back to sig_on().
@@ -350,7 +384,7 @@ static void cysigs_interrupt_handler(int sig)
350
384
if (cysigs .debug_level >= 3 ) print_backtrace ();
351
385
/* Store time of this signal, unless there is already a
352
386
* pending signal. */
353
- if (!cysigs .interrupt_received ) clock_gettime ( CLOCK_MONOTONIC , & sigtime );
387
+ if (!cysigs .interrupt_received ) get_monotonic_time ( & sigtime );
354
388
}
355
389
#endif
356
390
@@ -361,8 +395,10 @@ static void cysigs_interrupt_handler(int sig)
361
395
/* Raise an exception so Python can see it */
362
396
do_raise_exception (sig );
363
397
398
+ #if !_WIN32
364
399
/* Jump back to sig_on() (the first one if there is a stack) */
365
400
siglongjmp (trampoline , sig );
401
+ #endif
366
402
}
367
403
}
368
404
else
@@ -376,7 +412,11 @@ static void cysigs_interrupt_handler(int sig)
376
412
/* If we are here, we cannot handle the interrupt immediately, so
377
413
* we store the signal number for later use. But make sure we
378
414
* don't overwrite a SIGHUP or SIGTERM which we already received. */
379
- if (cysigs .interrupt_received != SIGHUP && cysigs .interrupt_received != SIGTERM )
415
+ if (
416
+ #ifdef SIGHUP
417
+ cysigs .interrupt_received != SIGHUP &&
418
+ #endif
419
+ cysigs .interrupt_received != SIGTERM )
380
420
{
381
421
cysigs .interrupt_received = sig ;
382
422
custom_set_pending_signal (sig );
@@ -393,24 +433,28 @@ static void cysigs_signal_handler(int sig)
393
433
int inside = cysigs .inside_signal_handler ;
394
434
cysigs .inside_signal_handler = 1 ;
395
435
396
- if (inside == 0 && cysigs .sig_on_count > 0 && sig != SIGQUIT )
397
- {
436
+ if (inside == 0 && cysigs .sig_on_count > 0
437
+ #ifdef SIGQUIT
438
+ && sig != SIGQUIT
439
+ #endif
440
+ ) {
398
441
/* We are inside sig_on(), so we can handle the signal! */
399
442
#if ENABLE_DEBUG_CYSIGNALS
400
443
if (cysigs .debug_level >= 1 ) {
401
444
print_stderr ("\n*** SIG " );
402
445
print_stderr_long (sig );
403
446
print_stderr (" *** inside sig_on\n" );
404
447
if (cysigs .debug_level >= 3 ) print_backtrace ();
405
- clock_gettime ( CLOCK_MONOTONIC , & sigtime );
448
+ get_monotonic_time ( & sigtime );
406
449
}
407
450
#endif
408
451
409
452
/* Raise an exception so Python can see it */
410
453
do_raise_exception (sig );
411
-
454
+ #if ! _WIN32
412
455
/* Jump back to sig_on() (the first one if there is a stack) */
413
456
siglongjmp (trampoline , sig );
457
+ #endif
414
458
}
415
459
else
416
460
{
@@ -422,7 +466,7 @@ static void cysigs_signal_handler(int sig)
422
466
}
423
467
}
424
468
425
-
469
+ #if ! _WIN32
426
470
/* A trampoline to jump to after handling a signal.
427
471
*
428
472
* The jump to sig_on() uses cylongjmp(), which does not restore the
@@ -506,6 +550,7 @@ static void setup_trampoline(void)
506
550
cylongjmp (trampoline_setup , 1 );
507
551
}
508
552
}
553
+ #endif
509
554
510
555
511
556
/* This calls sig_raise_exception() to actually raise the exception. */
@@ -514,7 +559,7 @@ static void do_raise_exception(int sig)
514
559
#if ENABLE_DEBUG_CYSIGNALS
515
560
struct timespec raisetime ;
516
561
if (cysigs .debug_level >= 2 ) {
517
- clock_gettime ( CLOCK_MONOTONIC , & raisetime );
562
+ get_monotonic_time ( & raisetime );
518
563
long delta_ms = (raisetime .tv_sec - sigtime .tv_sec )* 1000L + (raisetime .tv_nsec - sigtime .tv_nsec )/1000000L ;
519
564
PyGILState_STATE gilstate = PyGILState_Ensure ();
520
565
print_stderr ("do_raise_exception(sig=" );
@@ -608,6 +653,11 @@ static void setup_alt_stack(void)
608
653
609
654
static void setup_cysignals_handlers (void )
610
655
{
656
+ #ifdef _WIN32
657
+ signal (SIGINT , cysigs_interrupt_handler );
658
+ signal (SIGTERM , cysigs_interrupt_handler );
659
+ signal (SIGABRT , cysigs_signal_handler );
660
+ #else
611
661
struct sigaction sa ;
612
662
memset (& sa , 0 , sizeof (sa ));
613
663
@@ -635,21 +685,30 @@ static void setup_cysignals_handlers(void)
635
685
/* Handlers for interrupt-like signals */
636
686
sa .sa_handler = cysigs_interrupt_handler ;
637
687
sa .sa_flags = 0 ;
688
+ #ifdef SIGHUP
638
689
if (sigaction (SIGHUP , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
690
+ #endif
639
691
if (sigaction (SIGINT , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
692
+ #ifdef SIGALRM
640
693
if (sigaction (SIGALRM , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
694
+ #endif
641
695
642
696
/* Handlers for critical signals */
643
697
sa .sa_handler = cysigs_signal_handler ;
644
698
/* Allow signals during signal handling, we have code to deal with
645
699
* this case. */
646
700
sa .sa_flags = SA_NODEFER | SA_ONSTACK ;
701
+ #ifdef SIGQUIT
647
702
if (sigaction (SIGQUIT , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
703
+ #endif
648
704
if (sigaction (SIGILL , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
649
705
if (sigaction (SIGABRT , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
650
706
if (sigaction (SIGFPE , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
707
+ #ifdef SIGBUS
651
708
if (sigaction (SIGBUS , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
709
+ #endif
652
710
if (sigaction (SIGSEGV , & sa , NULL )) {perror ("cysignals sigaction" ); exit (1 );}
711
+ #endif
653
712
}
654
713
655
714
0 commit comments