[Python-checkins] cpython: Issue #8407: Fix the signal handler of the signal module: if it is called
victor.stinner
python-checkins at python.org
Wed May 25 02:38:28 CEST 2011
http://hg.python.org/cpython/rev/234021dcad93
changeset: 70368:234021dcad93
user: Victor Stinner <victor.stinner at haypocalc.com>
date: Wed May 25 02:35:58 2011 +0200
summary:
Issue #8407: Fix the signal handler of the signal module: if it is called
twice, it now writes the number of the second signal into the wakeup fd.
files:
Lib/test/test_signal.py | 36 +++++++++++++++++++++++++---
Modules/signalmodule.c | 9 ++++---
2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -226,10 +226,16 @@
TIMEOUT_FULL = 10
TIMEOUT_HALF = 5
- def check_signum(self, *signals):
+ def handler(self, signum, frame):
+ pass
+
+ def check_signum(self, *signals, **kw):
data = os.read(self.read, len(signals)+1)
raised = struct.unpack('%uB' % len(data), data)
- self.assertSequenceEqual(raised, signals)
+ if kw.get('unordered', False):
+ raised = set(raised)
+ signals = set(signals)
+ self.assertEqual(raised, signals)
def test_wakeup_fd_early(self):
import select
@@ -259,16 +265,38 @@
self.check_signum(signal.SIGALRM)
def test_signum(self):
- old_handler = signal.signal(signal.SIGUSR1, lambda x,y:None)
+ old_handler = signal.signal(signal.SIGUSR1, self.handler)
self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
os.kill(os.getpid(), signal.SIGUSR1)
os.kill(os.getpid(), signal.SIGALRM)
self.check_signum(signal.SIGUSR1, signal.SIGALRM)
+ @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
+ 'need signal.pthread_sigmask()')
+ @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
+ 'need signal.pthread_kill()')
+ def test_pending(self):
+ signum1 = signal.SIGUSR1
+ signum2 = signal.SIGUSR2
+ tid = threading.current_thread().ident
+
+ old_handler = signal.signal(signum1, self.handler)
+ self.addCleanup(signal.signal, signum1, old_handler)
+ old_handler = signal.signal(signum2, self.handler)
+ self.addCleanup(signal.signal, signum2, old_handler)
+
+ signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2))
+ signal.pthread_kill(tid, signum1)
+ signal.pthread_kill(tid, signum2)
+ # Unblocking the 2 signals calls the C signal handler twice
+ signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2))
+
+ self.check_signum(signum1, signum2, unordered=True)
+
def setUp(self):
import fcntl
- self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
+ self.alrm = signal.signal(signal.SIGALRM, self.handler)
self.read, self.write = os.pipe()
flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
flags = flags | os.O_NONBLOCK
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -177,17 +177,18 @@
trip_signal(int sig_num)
{
unsigned char byte;
+
Handlers[sig_num].tripped = 1;
+ if (wakeup_fd != -1) {
+ byte = (unsigned char)sig_num;
+ write(wakeup_fd, &byte, 1);
+ }
if (is_tripped)
return;
/* Set is_tripped after setting .tripped, as it gets
cleared in PyErr_CheckSignals() before .tripped. */
is_tripped = 1;
Py_AddPendingCall(checksignals_witharg, NULL);
- if (wakeup_fd != -1) {
- byte = (unsigned char)sig_num;
- write(wakeup_fd, &byte, 1);
- }
}
static void
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list