@@ -600,6 +600,10 @@ raise_exception(PyObject *self, PyObject *args)
600600 if (!PyArg_ParseTuple (args , "Oi:raise_exception" ,
601601 & exc , & num_args ))
602602 return NULL ;
603+ if (!PyExceptionClass_Check (exc )) {
604+ PyErr_Format (PyExc_TypeError , "an exception class is required" );
605+ return NULL ;
606+ }
603607
604608 exc_args = PyTuple_New (num_args );
605609 if (exc_args == NULL )
@@ -628,14 +632,17 @@ raise_exception(PyObject *self, PyObject *args)
628632 */
629633static PyThread_type_lock thread_done = NULL ;
630634
631- static void
635+ static int
632636_make_call (void * callable )
633637{
634638 PyObject * rc ;
639+ int success ;
635640 PyGILState_STATE s = PyGILState_Ensure ();
636641 rc = PyObject_CallFunction ((PyObject * )callable , "" );
642+ success = (rc != NULL );
637643 Py_XDECREF (rc );
638644 PyGILState_Release (s );
645+ return success ;
639646}
640647
641648/* Same thing, but releases `thread_done` when it returns. This variant
@@ -652,10 +659,17 @@ static PyObject *
652659test_thread_state (PyObject * self , PyObject * args )
653660{
654661 PyObject * fn ;
662+ int success = 1 ;
655663
656664 if (!PyArg_ParseTuple (args , "O:test_thread_state" , & fn ))
657665 return NULL ;
658666
667+ if (!PyCallable_Check (fn )) {
668+ PyErr_Format (PyExc_TypeError , "'%s' object is not callable" ,
669+ fn -> ob_type -> tp_name );
670+ return NULL ;
671+ }
672+
659673 /* Ensure Python is set up for threading */
660674 PyEval_InitThreads ();
661675 thread_done = PyThread_allocate_lock ();
@@ -666,10 +680,10 @@ test_thread_state(PyObject *self, PyObject *args)
666680 /* Start a new thread with our callback. */
667681 PyThread_start_new_thread (_make_call_from_thread , fn );
668682 /* Make the callback with the thread lock held by this thread */
669- _make_call (fn );
683+ success &= _make_call (fn );
670684 /* Do it all again, but this time with the thread-lock released */
671685 Py_BEGIN_ALLOW_THREADS
672- _make_call (fn );
686+ success &= _make_call (fn );
673687 PyThread_acquire_lock (thread_done , 1 ); /* wait for thread to finish */
674688 Py_END_ALLOW_THREADS
675689
@@ -679,14 +693,16 @@ test_thread_state(PyObject *self, PyObject *args)
679693 */
680694 Py_BEGIN_ALLOW_THREADS
681695 PyThread_start_new_thread (_make_call_from_thread , fn );
682- _make_call (fn );
696+ success &= _make_call (fn );
683697 PyThread_acquire_lock (thread_done , 1 ); /* wait for thread to finish */
684698 Py_END_ALLOW_THREADS
685699
686700 /* Release lock we acquired above. This is required on HP-UX. */
687701 PyThread_release_lock (thread_done );
688702
689703 PyThread_free_lock (thread_done );
704+ if (!success )
705+ return NULL ;
690706 Py_RETURN_NONE ;
691707}
692708#endif
0 commit comments