2 /* Signal module -- many thanks to Lance Ellinghaus */
4 /* XXX Signals should be recorded per thread, now we have thread state. */
19 #ifdef HAVE_SYS_STAT_H
22 #ifdef HAVE_SYS_TIME_H
27 #define SIG_ERR ((PyOS_sighandler_t)(-1))
30 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
37 # define NSIG _NSIG /* For BSD/SysV */
38 # elif defined(_SIGMAX)
39 # define NSIG (_SIGMAX + 1) /* For QNX */
40 # elif defined(SIGMAX)
41 # define NSIG (SIGMAX + 1) /* For djgpp */
43 # define NSIG 64 /* Use a reasonable default value */
49 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
51 When threads are supported, we want the following semantics:
53 - only the main thread can set a signal handler
54 - any thread can get a signal handler
55 - signals are only delivered to the main thread
57 I.e. we don't support "synchronous signals" like SIGFPE (catching
58 this doesn't make much sense in Python anyway) nor do we support
59 signals as a means of inter-thread communication, since not all
60 thread implementations support that (at least our thread library
63 We still have the problem that in some implementations signals
64 generated by the keyboard (e.g. SIGINT) are delivered to all
65 threads (e.g. SGI), while in others (e.g. Solaris) such signals are
66 delivered to one random thread (an intermediate possibility would
67 be to deliver it to the main thread -- POSIX?). For now, we have
68 a working implementation that works in all three cases -- the
69 handler ignores signals if getpid() isn't the same as in the main
70 thread. XXX This is a hack.
72 GNU pth is a user-space threading library, and as such, all threads
73 run within the same process. In this case, if the currently running
74 thread is not the main_thread, send the signal to the main_thread.
78 #include <sys/types.h> /* For pid_t */
80 static long main_thread
;
81 static pid_t main_pid
;
89 static sig_atomic_t wakeup_fd
= -1;
91 /* Speed up sigcheck() when none tripped */
92 static volatile sig_atomic_t is_tripped
= 0;
94 static PyObject
*DefaultHandler
;
95 static PyObject
*IgnoreHandler
;
96 static PyObject
*IntHandler
;
98 /* On Solaris 8, gcc will produce a warning that the function
99 declaration is not a prototype. This is caused by the definition of
100 SIG_DFL as (void (*)())0; the correct declaration would have been
103 static PyOS_sighandler_t old_siginthandler
= SIG_DFL
;
105 #ifdef HAVE_GETITIMER
106 static PyObject
*ItimerError
;
108 /* auxiliary functions for setitimer/getitimer */
110 timeval_from_double(double d
, struct timeval
*tv
)
112 tv
->tv_sec
= floor(d
);
113 tv
->tv_usec
= fmod(d
, 1.0) * 1000000.0;
116 Py_LOCAL_INLINE(double)
117 double_from_timeval(struct timeval
*tv
)
119 return tv
->tv_sec
+ (double)(tv
->tv_usec
/ 1000000.0);
123 itimer_retval(struct itimerval
*iv
)
131 if(!(v
= PyFloat_FromDouble(double_from_timeval(&iv
->it_value
)))) {
136 PyTuple_SET_ITEM(r
, 0, v
);
138 if(!(v
= PyFloat_FromDouble(double_from_timeval(&iv
->it_interval
)))) {
143 PyTuple_SET_ITEM(r
, 1, v
);
150 signal_default_int_handler(PyObject
*self
, PyObject
*args
)
152 PyErr_SetNone(PyExc_KeyboardInterrupt
);
156 PyDoc_STRVAR(default_int_handler_doc
,
157 "default_int_handler(...)\n\
159 The default handler for SIGINT installed by Python.\n\
160 It raises KeyboardInterrupt.");
164 checksignals_witharg(void * unused
)
166 return PyErr_CheckSignals();
170 trip_signal(int sig_num
)
172 Handlers
[sig_num
].tripped
= 1;
175 /* Set is_tripped after setting .tripped, as it gets
176 cleared in PyErr_CheckSignals() before .tripped. */
178 Py_AddPendingCall(checksignals_witharg
, NULL
);
180 write(wakeup_fd
, "\0", 1);
184 signal_handler(int sig_num
)
186 int save_errno
= errno
;
188 #if defined(WITH_THREAD) && defined(WITH_PTH)
189 if (PyThread_get_thread_ident() != main_thread
) {
190 pth_raise(*(pth_t
*) main_thread
, sig_num
);
196 /* See NOTES section above */
197 if (getpid() == main_pid
)
200 trip_signal(sig_num
);
203 #ifndef HAVE_SIGACTION
205 /* To avoid infinite recursion, this signal remains
206 reset until explicit re-instated.
207 Don't clear the 'func' field as it is our pointer
208 to the Python handler... */
209 if (sig_num
!= SIGCHLD
)
211 /* If the handler was not set up with sigaction, reinstall it. See
212 * Python/pythonrun.c for the implementation of PyOS_setsig which
213 * makes this true. See also issue8354. */
214 PyOS_setsig(sig_num
, signal_handler
);
218 /* Issue #10311: asynchronously executing signal handlers should not
219 mutate errno under the feet of unsuspecting C code. */
226 signal_alarm(PyObject
*self
, PyObject
*args
)
229 if (!PyArg_ParseTuple(args
, "i:alarm", &t
))
231 /* alarm() returns the number of seconds remaining */
232 return PyInt_FromLong((long)alarm(t
));
235 PyDoc_STRVAR(alarm_doc
,
238 Arrange for SIGALRM to arrive after the given number of seconds.");
243 signal_pause(PyObject
*self
)
245 Py_BEGIN_ALLOW_THREADS
248 /* make sure that any exceptions that got raised are propagated
251 if (PyErr_CheckSignals())
257 PyDoc_STRVAR(pause_doc
,
260 Wait until a signal arrives.");
266 signal_signal(PyObject
*self
, PyObject
*args
)
270 PyObject
*old_handler
;
272 if (!PyArg_ParseTuple(args
, "iO:signal", &sig_num
, &obj
))
275 /* Validate that sig_num is one of the allowable signals */
279 /* Issue #10003: SIGBREAK is not documented as permitted, but works
280 and corresponds to CTRL_BREAK_EVENT. */
281 case SIGBREAK
: break;
289 PyErr_SetString(PyExc_ValueError
, "invalid signal value");
294 if (PyThread_get_thread_ident() != main_thread
) {
295 PyErr_SetString(PyExc_ValueError
,
296 "signal only works in main thread");
300 if (sig_num
< 1 || sig_num
>= NSIG
) {
301 PyErr_SetString(PyExc_ValueError
,
302 "signal number out of range");
305 if (obj
== IgnoreHandler
)
307 else if (obj
== DefaultHandler
)
309 else if (!PyCallable_Check(obj
)) {
310 PyErr_SetString(PyExc_TypeError
,
311 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
315 func
= signal_handler
;
316 if (PyOS_setsig(sig_num
, func
) == SIG_ERR
) {
317 PyErr_SetFromErrno(PyExc_RuntimeError
);
320 old_handler
= Handlers
[sig_num
].func
;
321 Handlers
[sig_num
].tripped
= 0;
323 Handlers
[sig_num
].func
= obj
;
324 if (old_handler
!= NULL
)
330 PyDoc_STRVAR(signal_doc
,
331 "signal(sig, action) -> action\n\
333 Set the action for the given signal. The action can be SIG_DFL,\n\
334 SIG_IGN, or a callable Python object. The previous action is\n\
335 returned. See getsignal() for possible return values.\n\
337 *** IMPORTANT NOTICE ***\n\
338 A signal handler function is called with two arguments:\n\
339 the first is the signal number, the second is the interrupted stack frame.");
343 signal_getsignal(PyObject
*self
, PyObject
*args
)
346 PyObject
*old_handler
;
347 if (!PyArg_ParseTuple(args
, "i:getsignal", &sig_num
))
349 if (sig_num
< 1 || sig_num
>= NSIG
) {
350 PyErr_SetString(PyExc_ValueError
,
351 "signal number out of range");
354 old_handler
= Handlers
[sig_num
].func
;
355 if (old_handler
!= NULL
) {
356 Py_INCREF(old_handler
);
364 PyDoc_STRVAR(getsignal_doc
,
365 "getsignal(sig) -> action\n\
367 Return the current action for the given signal. The return value can be:\n\
368 SIG_IGN -- if the signal is being ignored\n\
369 SIG_DFL -- if the default action for the signal is in effect\n\
370 None -- if an unknown handler is in effect\n\
371 anything else -- the callable Python object used as a handler");
373 #ifdef HAVE_SIGINTERRUPT
374 PyDoc_STRVAR(siginterrupt_doc
,
375 "siginterrupt(sig, flag) -> None\n\
376 change system call restart behaviour: if flag is False, system calls\n\
377 will be restarted when interrupted by signal sig, else system calls\n\
378 will be interrupted.");
381 signal_siginterrupt(PyObject
*self
, PyObject
*args
)
386 if (!PyArg_ParseTuple(args
, "ii:siginterrupt", &sig_num
, &flag
))
388 if (sig_num
< 1 || sig_num
>= NSIG
) {
389 PyErr_SetString(PyExc_ValueError
,
390 "signal number out of range");
393 if (siginterrupt(sig_num
, flag
)<0) {
394 PyErr_SetFromErrno(PyExc_RuntimeError
);
405 signal_set_wakeup_fd(PyObject
*self
, PyObject
*args
)
409 if (!PyArg_ParseTuple(args
, "i:set_wakeup_fd", &fd
))
412 if (PyThread_get_thread_ident() != main_thread
) {
413 PyErr_SetString(PyExc_ValueError
,
414 "set_wakeup_fd only works in main thread");
418 if (fd
!= -1 && (!_PyVerify_fd(fd
) || fstat(fd
, &buf
) != 0)) {
419 PyErr_SetString(PyExc_ValueError
, "invalid fd");
424 return PyLong_FromLong(old_fd
);
427 PyDoc_STRVAR(set_wakeup_fd_doc
,
428 "set_wakeup_fd(fd) -> fd\n\
430 Sets the fd to be written to (with '\\0') when a signal\n\
431 comes in. A library can use this to wakeup select or poll.\n\
432 The previous fd is returned.\n\
434 The fd must be non-blocking.");
436 /* C API for the same, without all the error checking */
438 PySignal_SetWakeupFd(int fd
)
440 int old_fd
= wakeup_fd
;
448 #ifdef HAVE_SETITIMER
450 signal_setitimer(PyObject
*self
, PyObject
*args
)
455 struct itimerval
new, old
;
457 if(!PyArg_ParseTuple(args
, "id|d:setitimer", &which
, &first
, &interval
))
460 timeval_from_double(first
, &new.it_value
);
461 timeval_from_double(interval
, &new.it_interval
);
462 /* Let OS check "which" value */
463 if (setitimer(which
, &new, &old
) != 0) {
464 PyErr_SetFromErrno(ItimerError
);
468 return itimer_retval(&old
);
471 PyDoc_STRVAR(setitimer_doc
,
472 "setitimer(which, seconds[, interval])\n\
474 Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\
475 or ITIMER_PROF) to fire after value seconds and after\n\
476 that every interval seconds.\n\
477 The itimer can be cleared by setting seconds to zero.\n\
479 Returns old values as a tuple: (delay, interval).");
483 #ifdef HAVE_GETITIMER
485 signal_getitimer(PyObject
*self
, PyObject
*args
)
488 struct itimerval old
;
490 if (!PyArg_ParseTuple(args
, "i:getitimer", &which
))
493 if (getitimer(which
, &old
) != 0) {
494 PyErr_SetFromErrno(ItimerError
);
498 return itimer_retval(&old
);
501 PyDoc_STRVAR(getitimer_doc
,
504 Returns current value of given itimer.");
508 /* List of functions defined in the module */
509 static PyMethodDef signal_methods
[] = {
511 {"alarm", signal_alarm
, METH_VARARGS
, alarm_doc
},
513 #ifdef HAVE_SETITIMER
514 {"setitimer", signal_setitimer
, METH_VARARGS
, setitimer_doc
},
516 #ifdef HAVE_GETITIMER
517 {"getitimer", signal_getitimer
, METH_VARARGS
, getitimer_doc
},
519 {"signal", signal_signal
, METH_VARARGS
, signal_doc
},
520 {"getsignal", signal_getsignal
, METH_VARARGS
, getsignal_doc
},
521 {"set_wakeup_fd", signal_set_wakeup_fd
, METH_VARARGS
, set_wakeup_fd_doc
},
522 #ifdef HAVE_SIGINTERRUPT
523 {"siginterrupt", signal_siginterrupt
, METH_VARARGS
, siginterrupt_doc
},
526 {"pause", (PyCFunction
)signal_pause
,
527 METH_NOARGS
,pause_doc
},
529 {"default_int_handler", signal_default_int_handler
,
530 METH_VARARGS
, default_int_handler_doc
},
531 {NULL
, NULL
} /* sentinel */
535 PyDoc_STRVAR(module_doc
,
536 "This module provides mechanisms to use signal handlers in Python.\n\
540 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
541 setitimer() -- cause a signal (described below) after a specified\n\
542 float time and the timer may restart then [Unix only]\n\
543 getitimer() -- get current value of timer [Unix only]\n\
544 signal() -- set the action for a given signal\n\
545 getsignal() -- get the signal action for a given signal\n\
546 pause() -- wait until a signal arrives [Unix only]\n\
547 default_int_handler() -- default SIGINT handler\n\
550 SIG_DFL -- used to refer to the system default handler\n\
551 SIG_IGN -- used to ignore the signal\n\
552 NSIG -- number of defined signals\n\
553 SIGINT, SIGTERM, etc. -- signal numbers\n\
556 ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
558 ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
559 and delivers SIGVTALRM upon expiration\n\
560 ITIMER_PROF -- decrements both when the process is executing and\n\
561 when the system is executing on behalf of the process.\n\
562 Coupled with ITIMER_VIRTUAL, this timer is usually\n\
563 used to profile the time spent by the application\n\
564 in user and kernel space. SIGPROF is delivered upon\n\
567 *** IMPORTANT NOTICE ***\n\
568 A signal handler function is called with two arguments:\n\
569 the first is the signal number, the second is the interrupted stack frame.");
578 main_thread
= PyThread_get_thread_ident();
582 /* Create the module and add the functions */
583 m
= Py_InitModule3("signal", signal_methods
, module_doc
);
587 /* Add some symbolic constants to the module */
588 d
= PyModule_GetDict(m
);
590 x
= DefaultHandler
= PyLong_FromVoidPtr((void *)SIG_DFL
);
591 if (!x
|| PyDict_SetItemString(d
, "SIG_DFL", x
) < 0)
594 x
= IgnoreHandler
= PyLong_FromVoidPtr((void *)SIG_IGN
);
595 if (!x
|| PyDict_SetItemString(d
, "SIG_IGN", x
) < 0)
598 x
= PyInt_FromLong((long)NSIG
);
599 if (!x
|| PyDict_SetItemString(d
, "NSIG", x
) < 0)
603 x
= IntHandler
= PyDict_GetItemString(d
, "default_int_handler");
606 Py_INCREF(IntHandler
);
608 Handlers
[0].tripped
= 0;
609 for (i
= 1; i
< NSIG
; i
++) {
612 Handlers
[i
].tripped
= 0;
614 Handlers
[i
].func
= DefaultHandler
;
615 else if (t
== SIG_IGN
)
616 Handlers
[i
].func
= IgnoreHandler
;
618 Handlers
[i
].func
= Py_None
; /* None of our business */
619 Py_INCREF(Handlers
[i
].func
);
621 if (Handlers
[SIGINT
].func
== DefaultHandler
) {
622 /* Install default int handler */
623 Py_INCREF(IntHandler
);
624 Py_DECREF(Handlers
[SIGINT
].func
);
625 Handlers
[SIGINT
].func
= IntHandler
;
626 old_siginthandler
= PyOS_setsig(SIGINT
, signal_handler
);
630 x
= PyInt_FromLong(SIGHUP
);
631 PyDict_SetItemString(d
, "SIGHUP", x
);
635 x
= PyInt_FromLong(SIGINT
);
636 PyDict_SetItemString(d
, "SIGINT", x
);
640 x
= PyInt_FromLong(SIGBREAK
);
641 PyDict_SetItemString(d
, "SIGBREAK", x
);
645 x
= PyInt_FromLong(SIGQUIT
);
646 PyDict_SetItemString(d
, "SIGQUIT", x
);
650 x
= PyInt_FromLong(SIGILL
);
651 PyDict_SetItemString(d
, "SIGILL", x
);
655 x
= PyInt_FromLong(SIGTRAP
);
656 PyDict_SetItemString(d
, "SIGTRAP", x
);
660 x
= PyInt_FromLong(SIGIOT
);
661 PyDict_SetItemString(d
, "SIGIOT", x
);
665 x
= PyInt_FromLong(SIGABRT
);
666 PyDict_SetItemString(d
, "SIGABRT", x
);
670 x
= PyInt_FromLong(SIGEMT
);
671 PyDict_SetItemString(d
, "SIGEMT", x
);
675 x
= PyInt_FromLong(SIGFPE
);
676 PyDict_SetItemString(d
, "SIGFPE", x
);
680 x
= PyInt_FromLong(SIGKILL
);
681 PyDict_SetItemString(d
, "SIGKILL", x
);
685 x
= PyInt_FromLong(SIGBUS
);
686 PyDict_SetItemString(d
, "SIGBUS", x
);
690 x
= PyInt_FromLong(SIGSEGV
);
691 PyDict_SetItemString(d
, "SIGSEGV", x
);
695 x
= PyInt_FromLong(SIGSYS
);
696 PyDict_SetItemString(d
, "SIGSYS", x
);
700 x
= PyInt_FromLong(SIGPIPE
);
701 PyDict_SetItemString(d
, "SIGPIPE", x
);
705 x
= PyInt_FromLong(SIGALRM
);
706 PyDict_SetItemString(d
, "SIGALRM", x
);
710 x
= PyInt_FromLong(SIGTERM
);
711 PyDict_SetItemString(d
, "SIGTERM", x
);
715 x
= PyInt_FromLong(SIGUSR1
);
716 PyDict_SetItemString(d
, "SIGUSR1", x
);
720 x
= PyInt_FromLong(SIGUSR2
);
721 PyDict_SetItemString(d
, "SIGUSR2", x
);
725 x
= PyInt_FromLong(SIGCLD
);
726 PyDict_SetItemString(d
, "SIGCLD", x
);
730 x
= PyInt_FromLong(SIGCHLD
);
731 PyDict_SetItemString(d
, "SIGCHLD", x
);
735 x
= PyInt_FromLong(SIGPWR
);
736 PyDict_SetItemString(d
, "SIGPWR", x
);
740 x
= PyInt_FromLong(SIGIO
);
741 PyDict_SetItemString(d
, "SIGIO", x
);
745 x
= PyInt_FromLong(SIGURG
);
746 PyDict_SetItemString(d
, "SIGURG", x
);
750 x
= PyInt_FromLong(SIGWINCH
);
751 PyDict_SetItemString(d
, "SIGWINCH", x
);
755 x
= PyInt_FromLong(SIGPOLL
);
756 PyDict_SetItemString(d
, "SIGPOLL", x
);
760 x
= PyInt_FromLong(SIGSTOP
);
761 PyDict_SetItemString(d
, "SIGSTOP", x
);
765 x
= PyInt_FromLong(SIGTSTP
);
766 PyDict_SetItemString(d
, "SIGTSTP", x
);
770 x
= PyInt_FromLong(SIGCONT
);
771 PyDict_SetItemString(d
, "SIGCONT", x
);
775 x
= PyInt_FromLong(SIGTTIN
);
776 PyDict_SetItemString(d
, "SIGTTIN", x
);
780 x
= PyInt_FromLong(SIGTTOU
);
781 PyDict_SetItemString(d
, "SIGTTOU", x
);
785 x
= PyInt_FromLong(SIGVTALRM
);
786 PyDict_SetItemString(d
, "SIGVTALRM", x
);
790 x
= PyInt_FromLong(SIGPROF
);
791 PyDict_SetItemString(d
, "SIGPROF", x
);
795 x
= PyInt_FromLong(SIGXCPU
);
796 PyDict_SetItemString(d
, "SIGXCPU", x
);
800 x
= PyInt_FromLong(SIGXFSZ
);
801 PyDict_SetItemString(d
, "SIGXFSZ", x
);
805 x
= PyInt_FromLong(SIGRTMIN
);
806 PyDict_SetItemString(d
, "SIGRTMIN", x
);
810 x
= PyInt_FromLong(SIGRTMAX
);
811 PyDict_SetItemString(d
, "SIGRTMAX", x
);
815 x
= PyInt_FromLong(SIGINFO
);
816 PyDict_SetItemString(d
, "SIGINFO", x
);
821 x
= PyLong_FromLong(ITIMER_REAL
);
822 PyDict_SetItemString(d
, "ITIMER_REAL", x
);
825 #ifdef ITIMER_VIRTUAL
826 x
= PyLong_FromLong(ITIMER_VIRTUAL
);
827 PyDict_SetItemString(d
, "ITIMER_VIRTUAL", x
);
831 x
= PyLong_FromLong(ITIMER_PROF
);
832 PyDict_SetItemString(d
, "ITIMER_PROF", x
);
836 #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
837 ItimerError
= PyErr_NewException("signal.ItimerError",
838 PyExc_IOError
, NULL
);
839 if (ItimerError
!= NULL
)
840 PyDict_SetItemString(d
, "ItimerError", ItimerError
);
844 x
= PyInt_FromLong(CTRL_C_EVENT
);
845 PyDict_SetItemString(d
, "CTRL_C_EVENT", x
);
849 #ifdef CTRL_BREAK_EVENT
850 x
= PyInt_FromLong(CTRL_BREAK_EVENT
);
851 PyDict_SetItemString(d
, "CTRL_BREAK_EVENT", x
);
855 if (!PyErr_Occurred())
858 /* Check for errors */
869 PyOS_setsig(SIGINT
, old_siginthandler
);
870 old_siginthandler
= SIG_DFL
;
872 for (i
= 1; i
< NSIG
; i
++) {
873 func
= Handlers
[i
].func
;
874 Handlers
[i
].tripped
= 0;
875 Handlers
[i
].func
= NULL
;
876 if (i
!= SIGINT
&& func
!= NULL
&& func
!= Py_None
&&
877 func
!= DefaultHandler
&& func
!= IgnoreHandler
)
878 PyOS_setsig(i
, SIG_DFL
);
882 Py_XDECREF(IntHandler
);
884 Py_XDECREF(DefaultHandler
);
885 DefaultHandler
= NULL
;
886 Py_XDECREF(IgnoreHandler
);
887 IgnoreHandler
= NULL
;
891 /* Declared in pyerrors.h */
893 PyErr_CheckSignals(void)
902 if (PyThread_get_thread_ident() != main_thread
)
907 * The is_tripped variable is meant to speed up the calls to
908 * PyErr_CheckSignals (both directly or via pending calls) when no
909 * signal has arrived. This variable is set to 1 when a signal arrives
910 * and it is set to 0 here, when we know some signals arrived. This way
911 * we can run the registered handlers with no signals blocked.
913 * NOTE: with this approach we can have a situation where is_tripped is
914 * 1 but we have no more signals to handle (Handlers[i].tripped
915 * is 0 for every signal i). This won't do us any harm (except
916 * we're gonna spent some cycles for nothing). This happens when
917 * we receive a signal i after we zero is_tripped and before we
918 * check Handlers[i].tripped.
922 if (!(f
= (PyObject
*)PyEval_GetFrame()))
925 for (i
= 1; i
< NSIG
; i
++) {
926 if (Handlers
[i
].tripped
) {
927 PyObject
*result
= NULL
;
928 PyObject
*arglist
= Py_BuildValue("(iO)", i
, f
);
929 Handlers
[i
].tripped
= 0;
932 result
= PyEval_CallObject(Handlers
[i
].func
,
947 /* Replacements for intrcheck.c functionality
948 * Declared in pyerrors.h
951 PyErr_SetInterrupt(void)
957 PyOS_InitInterrupts(void)
960 _PyImport_FixupExtension("signal", "signal");
964 PyOS_FiniInterrupts(void)
970 PyOS_InterruptOccurred(void)
972 if (Handlers
[SIGINT
].tripped
) {
974 if (PyThread_get_thread_ident() != main_thread
)
977 Handlers
[SIGINT
].tripped
= 0;
984 _clear_pending_signals(void)
990 for (i
= 1; i
< NSIG
; ++i
) {
991 Handlers
[i
].tripped
= 0;
998 /* Clear the signal flags after forking so that they aren't handled
999 * in both processes if they came in just before the fork() but before
1000 * the interpreter had an opportunity to call the handlers. issue9535. */
1001 _clear_pending_signals();
1003 /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
1004 * can be called safely. */
1005 PyThread_ReInitTLS();
1006 PyEval_ReInitThreads();
1007 main_thread
= PyThread_get_thread_ident();
1008 main_pid
= getpid();
1009 _PyImport_ReInitLock();