cpython: a5890ff5e3d5 (original) (raw)
Mercurial > cpython
changeset 69821:a5890ff5e3d5
Issue #8407: signal.pthread_sigmask() returns a set instead of a list Update the doc. Refactor also related tests. [#8407]
Victor Stinner victor.stinner@haypocalc.com | |
---|---|
date | Wed, 04 May 2011 13:20:35 +0200 |
parents | 88dca05ed468 |
children | be5b8d1ded34 |
files | Doc/library/signal.rst Lib/test/test_signal.py Modules/signalmodule.c |
diffstat | 3 files changed, 59 insertions(+), 46 deletions(-)[+] [-] Doc/library/signal.rst 7 Lib/test/test_signal.py 33 Modules/signalmodule.c 65 |
line wrap: on
line diff
--- a/Doc/library/signal.rst
+++ b/Doc/library/signal.rst
@@ -184,7 +184,7 @@ The :mod:signal
module defines the fol
Fetch and/or change the signal mask of the calling thread. The signal mask
is the set of signals whose delivery is currently blocked for the caller.
- Return the old signal mask as a set of signals. The behavior of the call is dependent on the value of how, as follows.
@@ -196,8 +196,9 @@ The :mod:signal
module defines the fol
* :data:SIG_SETMASK
: The set of blocked signals is set to the mask
argument.
- mask is a set of signal numbers (e.g. {:const:
signal.SIGINT
, - :const:
signal.SIGTERM
}). Userange(1, signal.NSIG)
for a full mask - including all signals.
For example,
signal.pthread_sigmask(signal.SIG_BLOCK, [])
reads the signal mask of the calling thread.
--- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -486,24 +486,27 @@ class ItimerTest(unittest.TestCase): @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') -class PthreadSigmaskTests(unittest.TestCase):
+class PendingSignalsTests(unittest.TestCase):
- def test_pthread_sigmask_arguments(self): self.assertRaises(TypeError, signal.pthread_sigmask) self.assertRaises(TypeError, signal.pthread_sigmask, 1) self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3) self.assertRaises(RuntimeError, signal.pthread_sigmask, 1700, [])
def handler(signum, frame):[](#l2.31)
1/0[](#l2.32)
def read_sigmask():[](#l2.34)
return signal.pthread_sigmask(signal.SIG_BLOCK, [])[](#l2.35)
- # The fault handler timeout thread masks all signals. If the main # thread masks also SIGUSR1, all threads mask this signal. In this # case, if we send SIGUSR1 to the process, the signal is pending in the @@ -527,7 +530,7 @@ class PthreadSigmaskTests(unittest.TestC "blocked by pthread_sigmask() (issue #11998)") # Install our signal handler
old_handler = signal.signal(signum, handler)[](#l2.44)
old_handler = signal.signal(signum, self.handler)[](#l2.45) self.addCleanup(signal.signal, signum, old_handler)[](#l2.46)
# Unblock SIGUSR1 (and copy the old mask) to test our signal handler @@ -543,9 +546,9 @@ class PthreadSigmaskTests(unittest.TestC os.kill(pid, signum) # Check the new mask
blocked = read_sigmask()[](#l2.53)
blocked = self.read_sigmask()[](#l2.54) self.assertIn(signum, blocked)[](#l2.55)
self.assertEqual(set(old_mask) ^ set(blocked), {signum})[](#l2.56)
self.assertEqual(old_mask ^ blocked, {signum})[](#l2.57)
# Unblock SIGUSR1 if can_test_blocked_signals: @@ -558,9 +561,9 @@ class PthreadSigmaskTests(unittest.TestC os.kill(pid, signum) # Check the new mask
unblocked = read_sigmask()[](#l2.65)
unblocked = self.read_sigmask()[](#l2.66) self.assertNotIn(signum, unblocked)[](#l2.67)
self.assertEqual(set(blocked) ^ set(unblocked), {signum})[](#l2.68)
self.assertEqual(blocked ^ unblocked, {signum})[](#l2.69) self.assertSequenceEqual(old_mask, unblocked)[](#l2.70) # Finally, restore the previous signal handler and the signal mask[](#l2.71)
@@ -570,7 +573,7 @@ def test_main(): support.run_unittest(BasicSignalTests, InterProcessSignalTests, WakeupSignalTests, SiginterruptTest, ItimerTest, WindowsSignalTests,
PthreadSigmaskTests)[](#l2.77)
--- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -552,11 +552,45 @@ error: return result; } +static PyObject* +sigset_to_set(sigset_t mask) +{
/* Handle the case where it is a member by adding the signal to[](#l3.21)
the result list. Ignore the other cases because they mean the[](#l3.22)
signal isn't a member of the mask or the signal was invalid,[](#l3.23)
and an invalid signal must have been our fault in constructing[](#l3.24)
the loop boundaries. */[](#l3.25)
signum = PyLong_FromLong(sig);[](#l3.26)
if (signum == NULL) {[](#l3.27)
Py_DECREF(result);[](#l3.28)
return NULL;[](#l3.29)
}[](#l3.30)
if (PySet_Add(result, signum) == -1) {[](#l3.31)
Py_DECREF(signum);[](#l3.32)
Py_DECREF(result);[](#l3.33)
return NULL;[](#l3.34)
}[](#l3.35)
Py_DECREF(signum);[](#l3.36)
- }
- return result;
+} + static PyObject * signal_pthread_sigmask(PyObject *self, PyObject *args) {
- int how;
- PyObject *signals; sigset_t mask, previous; int err; @@ -577,32 +611,7 @@ signal_pthread_sigmask(PyObject *self, P if (PyErr_CheckSignals()) return NULL;
- for (sig = 1; sig < NSIG; sig++) {
if (sigismember(&previous, sig) != 1)[](#l3.60)
continue;[](#l3.61)
/* Handle the case where it is a member by adding the signal to[](#l3.63)
the result list. Ignore the other cases because they mean the[](#l3.64)
signal isn't a member of the mask or the signal was invalid,[](#l3.65)
and an invalid signal must have been our fault in constructing[](#l3.66)
the loop boundaries. */[](#l3.67)
signum = PyLong_FromLong(sig);[](#l3.68)
if (signum == NULL) {[](#l3.69)
Py_DECREF(result);[](#l3.70)
return NULL;[](#l3.71)
}[](#l3.72)
if (PyList_Append(result, signum) == -1) {[](#l3.73)
Py_DECREF(signum);[](#l3.74)
Py_DECREF(result);[](#l3.75)
return NULL;[](#l3.76)
}[](#l3.77)
Py_DECREF(signum);[](#l3.78)
- }
- return result;