diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-03 12:57:12 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-03 12:57:12 (GMT) |
commit | d0e516db50376ab0fd729c42bafda3e5a6225b94 (patch) | |
tree | 125054b4762cd8c0bed63d1a4b82c135f8d5275f | |
parent | 2d4a91e0d0065b89cb9820b10e30f74c362cb430 (diff) | |
download | cpython-d0e516db50376ab0fd729c42bafda3e5a6225b94.zip cpython-d0e516db50376ab0fd729c42bafda3e5a6225b94.tar.gz cpython-d0e516db50376ab0fd729c42bafda3e5a6225b94.tar.bz2 |
Issue #8407: pthread_sigmask() checks immediatly if signal handlers have been
called. The test checks that SIG_UNBLOCK calls immediatly the signal handler of
the pending SIGUSR1. Improve also the tests using an exception (division by
zero) instead of a flag (a function attribute).
-rw-r--r-- | Lib/test/test_signal.py | 30 | ||||
-rw-r--r-- | Modules/signalmodule.c | 4 |
2 files changed, 20 insertions, 14 deletions
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 5caf13d..1a28ced 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -498,8 +498,7 @@ class PthreadSigmaskTests(unittest.TestCase): signum = signal.SIGUSR1 def handler(signum, frame): - handler.tripped = True - handler.tripped = False + 1/0 def read_sigmask(): return signal.pthread_sigmask(signal.SIG_BLOCK, []) @@ -519,36 +518,39 @@ class PthreadSigmaskTests(unittest.TestCase): # function. faulthandler.cancel_dump_tracebacks_later() + # Install our signal handler old_handler = signal.signal(signum, handler) self.addCleanup(signal.signal, signum, old_handler) - # unblock SIGUSR1, copy the old mask and test our signal handler + # Unblock SIGUSR1 (and copy the old mask) to test our signal handler old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) self.addCleanup(signal.pthread_sigmask, signal.SIG_SETMASK, old_mask) - os.kill(pid, signum) - self.assertTrue(handler.tripped) + with self.assertRaises(ZeroDivisionError): + os.kill(pid, signum) - # block SIGUSR1 - handler.tripped = False + # Block and then raise SIGUSR1. The signal is blocked: the signal + # handler is not called, and the signal is now pending signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) os.kill(pid, signum) - self.assertFalse(handler.tripped) - # check the mask + # Check the new mask blocked = read_sigmask() self.assertIn(signum, blocked) self.assertEqual(set(old_mask) ^ set(blocked), {signum}) - # unblock SIGUSR1 - signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) - os.kill(pid, signum) - self.assertTrue(handler.tripped) + # Unblock SIGUSR1 + with self.assertRaises(ZeroDivisionError): + # unblock the pending signal calls immediatly the signal handler + signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) + with self.assertRaises(ZeroDivisionError): + os.kill(pid, signum) - # check the mask + # Check the new mask unblocked = read_sigmask() self.assertNotIn(signum, unblocked) self.assertEqual(set(blocked) ^ set(unblocked), {signum}) self.assertSequenceEqual(old_mask, unblocked) + # Finally, restore the previous signal handler and the signal mask def test_main(): diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 0cb2720..387dc8c 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -573,6 +573,10 @@ signal_pthread_sigmask(PyObject *self, PyObject *args) return NULL; } + /* if signals was unblocked, signal handlers have been called */ + if (PyErr_CheckSignals()) + return NULL; + result = PyList_New(0); if (result == NULL) return NULL; |