1313
1414#ifdef WITH_THREAD
1515# define FAULTHANDLER_LATER
16- # define FAULTHANDLER_WATCHDOG
1716#endif
1817
1918#ifndef MS_WINDOWS
@@ -66,20 +65,6 @@ static struct {
6665} thread ;
6766#endif
6867
69- #ifdef FAULTHANDLER_WATCHDOG
70- static struct {
71- int rfd ;
72- int wfd ;
73- PY_TIMEOUT_T period_us ; /* period in microseconds */
74- /* The main thread always holds this lock. It is only released when
75- faulthandler_watchdog() is interrupted before this thread exits, or at
76- Python exit. */
77- PyThread_type_lock cancel_event ;
78- /* released by child thread when joined */
79- PyThread_type_lock running ;
80- } watchdog ;
81- #endif
82-
8368#ifdef FAULTHANDLER_USER
8469typedef struct {
8570 int enabled ;
@@ -604,139 +589,6 @@ faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
604589}
605590#endif /* FAULTHANDLER_LATER */
606591
607- #ifdef FAULTHANDLER_WATCHDOG
608-
609- static void
610- file_watchdog (void * unused )
611- {
612- PyLockStatus st ;
613- PY_TIMEOUT_T timeout ;
614-
615- #define MAXDATA 1024
616- char buf1 [MAXDATA ], buf2 [MAXDATA ];
617- char * data = buf1 , * old_data = buf2 ;
618- Py_ssize_t data_len , old_data_len = -1 ;
619-
620- #if defined(HAVE_PTHREAD_SIGMASK ) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK )
621- sigset_t set ;
622-
623- /* we don't want to receive any signal */
624- sigfillset (& set );
625- pthread_sigmask (SIG_SETMASK , & set , NULL );
626- #endif
627-
628- /* On first pass, feed file contents immediately */
629- timeout = 0 ;
630- do {
631- st = PyThread_acquire_lock_timed (watchdog .cancel_event ,
632- timeout , 0 );
633- timeout = watchdog .period_us ;
634- if (st == PY_LOCK_ACQUIRED ) {
635- PyThread_release_lock (watchdog .cancel_event );
636- break ;
637- }
638- /* Timeout => read and write data */
639- assert (st == PY_LOCK_FAILURE );
640-
641- if (lseek (watchdog .rfd , 0 , SEEK_SET ) < 0 ) {
642- break ;
643- }
644- data_len = read (watchdog .rfd , data , MAXDATA );
645- if (data_len < 0 ) {
646- break ;
647- }
648- if (data_len != old_data_len || memcmp (data , old_data , data_len )) {
649- char * tdata ;
650- Py_ssize_t tlen ;
651- /* Contents changed, feed them to wfd */
652- long x = (long ) data_len ;
653- /* We can't do anything if the consumer is too slow, just bail out */
654- if (write (watchdog .wfd , (void * ) & x , sizeof (x )) < sizeof (x ))
655- break ;
656- if (write (watchdog .wfd , data , data_len ) < data_len )
657- break ;
658- tdata = data ;
659- data = old_data ;
660- old_data = tdata ;
661- tlen = data_len ;
662- data_len = old_data_len ;
663- old_data_len = tlen ;
664- }
665- } while (1 );
666-
667- close (watchdog .rfd );
668- close (watchdog .wfd );
669-
670- /* The only way out */
671- PyThread_release_lock (watchdog .running );
672- #undef MAXDATA
673- }
674-
675- static void
676- cancel_file_watchdog (void )
677- {
678- /* Notify cancellation */
679- PyThread_release_lock (watchdog .cancel_event );
680-
681- /* Wait for thread to join */
682- PyThread_acquire_lock (watchdog .running , 1 );
683- PyThread_release_lock (watchdog .running );
684-
685- /* The main thread should always hold the cancel_event lock */
686- PyThread_acquire_lock (watchdog .cancel_event , 1 );
687- }
688-
689- static PyObject *
690- faulthandler_file_watchdog (PyObject * self ,
691- PyObject * args , PyObject * kwargs )
692- {
693- static char * kwlist [] = {"rfd" , "wfd" , "period" , NULL };
694- double period ;
695- PY_TIMEOUT_T period_us ;
696- int rfd , wfd ;
697-
698- if (!PyArg_ParseTupleAndKeywords (args , kwargs ,
699- "iid:_file_watchdog" , kwlist ,
700- & rfd , & wfd , & period ))
701- return NULL ;
702- if ((period * 1e6 ) >= (double ) PY_TIMEOUT_MAX ) {
703- PyErr_SetString (PyExc_OverflowError , "period value is too large" );
704- return NULL ;
705- }
706- period_us = (PY_TIMEOUT_T )(period * 1e6 );
707- if (period_us <= 0 ) {
708- PyErr_SetString (PyExc_ValueError , "period must be greater than 0" );
709- return NULL ;
710- }
711-
712- /* Cancel previous thread, if running */
713- cancel_file_watchdog ();
714-
715- watchdog .rfd = rfd ;
716- watchdog .wfd = wfd ;
717- watchdog .period_us = period_us ;
718-
719- /* Arm these locks to serve as events when released */
720- PyThread_acquire_lock (watchdog .running , 1 );
721-
722- if (PyThread_start_new_thread (file_watchdog , NULL ) == -1 ) {
723- PyThread_release_lock (watchdog .running );
724- PyErr_SetString (PyExc_RuntimeError ,
725- "unable to start file watchdog thread" );
726- return NULL ;
727- }
728-
729- Py_RETURN_NONE ;
730- }
731-
732- static PyObject *
733- faulthandler_cancel_file_watchdog (PyObject * self )
734- {
735- cancel_file_watchdog ();
736- Py_RETURN_NONE ;
737- }
738- #endif /* FAULTHANDLER_WATCHDOG */
739-
740592#ifdef FAULTHANDLER_USER
741593static int
742594faulthandler_register (int signum , int chain , _Py_sighandler_t * p_previous )
@@ -1126,18 +978,6 @@ static PyMethodDef module_methods[] = {
1126978 "to dump_tracebacks_later()." )},
1127979#endif
1128980
1129- #ifdef FAULTHANDLER_WATCHDOG
1130- {"_file_watchdog" ,
1131- (PyCFunction )faulthandler_file_watchdog , METH_VARARGS |METH_KEYWORDS ,
1132- PyDoc_STR ("_file_watchdog(rfd, wfd, period):\n"
1133- "feed the contents of 'rfd' to 'wfd', if changed,\n"
1134- "every 'period seconds'." )},
1135- {"_cancel_file_watchdog" ,
1136- (PyCFunction )faulthandler_cancel_file_watchdog , METH_NOARGS ,
1137- PyDoc_STR ("_cancel_file_watchdog():\ncancel the previous call "
1138- "to _file_watchdog()." )},
1139- #endif
1140-
1141981#ifdef FAULTHANDLER_USER
1142982 {"register" ,
1143983 (PyCFunction )faulthandler_register_py , METH_VARARGS |METH_KEYWORDS ,
@@ -1263,16 +1103,6 @@ int _PyFaulthandler_Init(void)
12631103 }
12641104 PyThread_acquire_lock (thread .cancel_event , 1 );
12651105#endif
1266- #ifdef FAULTHANDLER_WATCHDOG
1267- watchdog .cancel_event = PyThread_allocate_lock ();
1268- watchdog .running = PyThread_allocate_lock ();
1269- if (!watchdog .cancel_event || !watchdog .running ) {
1270- PyErr_SetString (PyExc_RuntimeError ,
1271- "could not allocate locks for faulthandler" );
1272- return -1 ;
1273- }
1274- PyThread_acquire_lock (watchdog .cancel_event , 1 );
1275- #endif
12761106
12771107 return faulthandler_env_options ();
12781108}
@@ -1297,20 +1127,6 @@ void _PyFaulthandler_Fini(void)
12971127 }
12981128#endif
12991129
1300- #ifdef FAULTHANDLER_WATCHDOG
1301- /* file watchdog */
1302- if (watchdog .cancel_event ) {
1303- cancel_file_watchdog ();
1304- PyThread_release_lock (watchdog .cancel_event );
1305- PyThread_free_lock (watchdog .cancel_event );
1306- watchdog .cancel_event = NULL ;
1307- }
1308- if (watchdog .running ) {
1309- PyThread_free_lock (watchdog .running );
1310- watchdog .running = NULL ;
1311- }
1312- #endif
1313-
13141130#ifdef FAULTHANDLER_USER
13151131 /* user */
13161132 if (user_signals != NULL ) {
0 commit comments