summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2011-06-09 23:39:53 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2011-06-09 23:39:53 (GMT)
commit10c30d676432b995d19308855a5ed40f87353074 (patch)
tree3891dd9f9c15dc035362f5eb583a41b6e1f02462
parent589f89e2ad08a6cae34d90b227d3ffcfe1c06216 (diff)
downloadcpython-10c30d676432b995d19308855a5ed40f87353074.zip
cpython-10c30d676432b995d19308855a5ed40f87353074.tar.gz
cpython-10c30d676432b995d19308855a5ed40f87353074.tar.bz2
Issue #8407: signal.sigwait() releases the GIL
Initial patch by Charles-François Natali.
-rw-r--r--Lib/test/test_signal.py19
-rw-r--r--Modules/signalmodule.c2
2 files changed, 21 insertions, 0 deletions
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 0631390..1ed4b9e 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -607,6 +607,25 @@ class PendingSignalsTests(unittest.TestCase):
signal.alarm(1)
self.assertEqual(signal.sigwait([signal.SIGALRM]), signal.SIGALRM)
+ @unittest.skipUnless(hasattr(signal, 'sigwait'),
+ 'need signal.sigwait()')
+ @unittest.skipIf(threading is None, "test needs threading module")
+ def test_sigwait_thread(self):
+ signum = signal.SIGUSR1
+ old_handler = signal.signal(signum, self.handler)
+ self.addCleanup(signal.signal, signum, old_handler)
+
+ def kill_later():
+ time.sleep(1)
+ os.kill(os.getpid(), signum)
+
+ killer = threading.Thread(target=kill_later)
+ killer.start()
+ try:
+ self.assertEqual(signal.sigwait([signum]), signum)
+ finally:
+ killer.join()
+
@unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
'need signal.pthread_sigmask()')
def test_pthread_sigmask_arguments(self):
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 6d27ab3..94e6bcb 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -662,7 +662,9 @@ signal_sigwait(PyObject *self, PyObject *args)
if (iterable_to_sigset(signals, &set))
return NULL;
+ Py_BEGIN_ALLOW_THREADS
err = sigwait(&set, &signum);
+ Py_END_ALLOW_THREADS
if (err) {
errno = err;
return PyErr_SetFromErrno(PyExc_OSError);