blob: fdeb4c2261f9746bbea886e0fac28c72eec8061b [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Raymond Hettinger722d8c32009-06-18 22:21:03 +00003from contextlib import closing
Christian Heimescc47b052008-03-25 14:56:36 +00004import gc
Christian Heimes4fbc72b2008-03-22 00:47:35 +00005import pickle
6import select
Guido van Rossum4f17e3e1995-03-16 15:07:38 +00007import signal
Victor Stinnerd49b1f12011-05-08 02:03:15 +02008import struct
Christian Heimes4fbc72b2008-03-22 00:47:35 +00009import subprocess
10import traceback
Christian Heimesc06950e2008-02-28 21:17:00 +000011import sys, os, time, errno
Victor Stinnerd6284962011-06-20 23:28:09 +020012from test.script_helper import assert_python_ok, spawn_python
Victor Stinnerb3e72192011-05-08 01:46:11 +020013try:
14 import threading
15except ImportError:
16 threading = None
Christian Heimesc06950e2008-02-28 21:17:00 +000017
Brian Curtin912443c2010-09-06 16:10:04 +000018if sys.platform in ('os2', 'riscos'):
19 raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
Christian Heimesc06950e2008-02-28 21:17:00 +000020
Guido van Rossumcc5a91d1997-04-16 00:29:15 +000021
Armin Rigo8b2cbfd2004-08-07 21:27:43 +000022class HandlerBCalled(Exception):
23 pass
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000024
Christian Heimes4fbc72b2008-03-22 00:47:35 +000025
26def exit_subprocess():
27 """Use os._exit(0) to exit the current subprocess.
28
29 Otherwise, the test catches the SystemExit and continues executing
30 in parallel with the original test, so you wind up with an
31 exponential number of tests running concurrently.
32 """
33 os._exit(0)
34
35
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000036def ignoring_eintr(__func, *args, **kwargs):
37 try:
38 return __func(*args, **kwargs)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +000039 except EnvironmentError as e:
40 if e.errno != errno.EINTR:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000041 raise
42 return None
43
44
Brian Curtin3f004b12010-08-06 19:34:52 +000045@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +000046class InterProcessSignalTests(unittest.TestCase):
47 MAX_DURATION = 20 # Entire test should last at most 20 sec.
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000048
Christian Heimescc47b052008-03-25 14:56:36 +000049 def setUp(self):
50 self.using_gc = gc.isenabled()
51 gc.disable()
52
53 def tearDown(self):
54 if self.using_gc:
55 gc.enable()
56
Christian Heimes5e696852008-04-09 08:37:03 +000057 def format_frame(self, frame, limit=None):
58 return ''.join(traceback.format_stack(frame, limit=limit))
59
60 def handlerA(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000061 self.a_called = True
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000062
Christian Heimes5e696852008-04-09 08:37:03 +000063 def handlerB(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000064 self.b_called = True
Christian Heimes5e696852008-04-09 08:37:03 +000065 raise HandlerBCalled(signum, self.format_frame(frame))
Neal Norwitz9730bcb2006-01-23 07:50:06 +000066
Christian Heimes4fbc72b2008-03-22 00:47:35 +000067 def wait(self, child):
68 """Wait for child to finish, ignoring EINTR."""
69 while True:
70 try:
71 child.wait()
72 return
73 except OSError as e:
74 if e.errno != errno.EINTR:
75 raise
Fred Drake004d5e62000-10-23 17:22:08 +000076
Christian Heimes4fbc72b2008-03-22 00:47:35 +000077 def run_test(self):
78 # Install handlers. This function runs in a sub-process, so we
79 # don't worry about re-setting the default handlers.
80 signal.signal(signal.SIGHUP, self.handlerA)
81 signal.signal(signal.SIGUSR1, self.handlerB)
82 signal.signal(signal.SIGUSR2, signal.SIG_IGN)
83 signal.signal(signal.SIGALRM, signal.default_int_handler)
Michael W. Hudson5c26e862004-06-11 18:09:28 +000084
Christian Heimes4fbc72b2008-03-22 00:47:35 +000085 # Variables the signals will modify:
86 self.a_called = False
87 self.b_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000088
Christian Heimes4fbc72b2008-03-22 00:47:35 +000089 # Let the sub-processes know who to send signals to.
90 pid = os.getpid()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000091
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000092 child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)])
93 if child:
94 self.wait(child)
95 if not self.a_called:
96 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +000097 self.assertTrue(self.a_called)
98 self.assertFalse(self.b_called)
99 self.a_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000100
Christian Heimes5e696852008-04-09 08:37:03 +0000101 # Make sure the signal isn't delivered while the previous
102 # Popen object is being destroyed, because __del__ swallows
103 # exceptions.
104 del child
Thomas Woutersed03b412007-08-28 21:37:11 +0000105 try:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000106 child = subprocess.Popen(['kill', '-USR1', str(pid)])
107 # This wait should be interrupted by the signal's exception.
108 self.wait(child)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000109 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000110 self.fail('HandlerBCalled exception not thrown')
111 except HandlerBCalled:
112 self.assertTrue(self.b_called)
113 self.assertFalse(self.a_called)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000114
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000115 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
116 if child:
117 self.wait(child) # Nothing should happen.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000118
119 try:
120 signal.alarm(1)
121 # The race condition in pause doesn't matter in this case,
122 # since alarm is going to raise a KeyboardException, which
123 # will skip the call.
124 signal.pause()
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000125 # But if another signal arrives before the alarm, pause
126 # may return early.
127 time.sleep(1)
Thomas Woutersed03b412007-08-28 21:37:11 +0000128 except KeyboardInterrupt:
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200129 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000130 except:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000131 self.fail("Some other exception woke us from pause: %s" %
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000132 traceback.format_exc())
133 else:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000134 self.fail("pause returned of its own accord, and the signal"
135 " didn't arrive after another second.")
Thomas Woutersed03b412007-08-28 21:37:11 +0000136
R. David Murray44546f82010-04-21 01:59:28 +0000137 # Issue 3864, unknown if this affects earlier versions of freebsd also
138 @unittest.skipIf(sys.platform=='freebsd6',
139 'inter process signals not reliable (do not mix well with threading) '
140 'on freebsd6')
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000141 def test_main(self):
142 # This function spawns a child process to insulate the main
143 # test-running process from all the signals. It then
144 # communicates with that child process over a pipe and
145 # re-raises information about any exceptions the child
146 # throws. The real work happens in self.run_test().
147 os_done_r, os_done_w = os.pipe()
Raymond Hettinger686057b2009-06-04 00:11:54 +0000148 with closing(os.fdopen(os_done_r, 'rb')) as done_r, \
149 closing(os.fdopen(os_done_w, 'wb')) as done_w:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000150 child = os.fork()
151 if child == 0:
152 # In the child process; run the test and report results
153 # through the pipe.
154 try:
155 done_r.close()
156 # Have to close done_w again here because
157 # exit_subprocess() will skip the enclosing with block.
158 with closing(done_w):
159 try:
160 self.run_test()
161 except:
162 pickle.dump(traceback.format_exc(), done_w)
163 else:
164 pickle.dump(None, done_w)
165 except:
166 print('Uh oh, raised from pickle.')
167 traceback.print_exc()
168 finally:
169 exit_subprocess()
170
171 done_w.close()
172 # Block for up to MAX_DURATION seconds for the test to finish.
173 r, w, x = select.select([done_r], [], [], self.MAX_DURATION)
174 if done_r in r:
175 tb = pickle.load(done_r)
176 if tb:
177 self.fail(tb)
178 else:
179 os.kill(child, signal.SIGKILL)
180 self.fail('Test deadlocked after %d seconds.' %
181 self.MAX_DURATION)
Thomas Woutersed03b412007-08-28 21:37:11 +0000182
183
Brian Curtin3f004b12010-08-06 19:34:52 +0000184@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Victor Stinnerb3e72192011-05-08 01:46:11 +0200185class PosixTests(unittest.TestCase):
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000186 def trivial_signal_handler(self, *args):
187 pass
188
Thomas Woutersed03b412007-08-28 21:37:11 +0000189 def test_out_of_range_signal_number_raises_error(self):
190 self.assertRaises(ValueError, signal.getsignal, 4242)
191
Thomas Woutersed03b412007-08-28 21:37:11 +0000192 self.assertRaises(ValueError, signal.signal, 4242,
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000193 self.trivial_signal_handler)
Thomas Woutersed03b412007-08-28 21:37:11 +0000194
195 def test_setting_signal_handler_to_none_raises_error(self):
196 self.assertRaises(TypeError, signal.signal,
197 signal.SIGUSR1, None)
198
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000199 def test_getsignal(self):
200 hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000201 self.assertEqual(signal.getsignal(signal.SIGHUP),
202 self.trivial_signal_handler)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000203 signal.signal(signal.SIGHUP, hup)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000204 self.assertEqual(signal.getsignal(signal.SIGHUP), hup)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000205
206
Brian Curtin3f004b12010-08-06 19:34:52 +0000207@unittest.skipUnless(sys.platform == "win32", "Windows specific")
208class WindowsSignalTests(unittest.TestCase):
209 def test_issue9324(self):
Brian Curtineccd4d92010-10-01 15:09:53 +0000210 # Updated for issue #10003, adding SIGBREAK
Brian Curtin3f004b12010-08-06 19:34:52 +0000211 handler = lambda x, y: None
Brian Curtineccd4d92010-10-01 15:09:53 +0000212 for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE,
213 signal.SIGILL, signal.SIGINT, signal.SIGSEGV,
214 signal.SIGTERM):
215 # Set and then reset a handler for signals that work on windows
216 signal.signal(sig, signal.signal(sig, handler))
Brian Curtin3f004b12010-08-06 19:34:52 +0000217
218 with self.assertRaises(ValueError):
219 signal.signal(-1, handler)
Brian Curtin80cd4bf2010-08-07 03:52:38 +0000220
221 with self.assertRaises(ValueError):
222 signal.signal(7, handler)
Brian Curtin3f004b12010-08-06 19:34:52 +0000223
224
225@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000226class WakeupSignalTests(unittest.TestCase):
Charles-François Natali027f9a32011-10-02 18:36:05 +0200227 def check_wakeup(self, test_body, *signals, ordered=True):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200228 # use a subprocess to have only one thread
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200229 code = """if 1:
230 import fcntl
231 import os
232 import signal
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200233 import struct
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000234
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200235 signals = {!r}
Victor Stinnerc13ef662011-05-25 02:35:58 +0200236
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200237 def handler(signum, frame):
238 pass
239
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200240 def check_signum(signals):
241 data = os.read(read, len(signals)+1)
242 raised = struct.unpack('%uB' % len(data), data)
Charles-François Natali027f9a32011-10-02 18:36:05 +0200243 if not {!r}:
244 raised = set(raised)
245 signals = set(signals)
Victor Stinner0a01f132011-07-04 18:06:35 +0200246 if raised != signals:
247 raise Exception("%r != %r" % (raised, signals))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200248
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200249 {}
250
251 signal.signal(signal.SIGALRM, handler)
252 read, write = os.pipe()
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200253 for fd in (read, write):
254 flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
255 flags = flags | os.O_NONBLOCK
256 fcntl.fcntl(fd, fcntl.F_SETFL, flags)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200257 signal.set_wakeup_fd(write)
258
259 test()
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200260 check_signum(signals)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200261
262 os.close(read)
263 os.close(write)
Charles-François Natali027f9a32011-10-02 18:36:05 +0200264 """.format(signals, ordered, test_body)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200265
266 assert_python_ok('-c', code)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200267
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000268 def test_wakeup_fd_early(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200269 self.check_wakeup("""def test():
270 import select
271 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000272
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200273 TIMEOUT_FULL = 10
274 TIMEOUT_HALF = 5
275
276 signal.alarm(1)
277 before_time = time.time()
278 # We attempt to get a signal during the sleep,
279 # before select is called
280 time.sleep(TIMEOUT_FULL)
281 mid_time = time.time()
282 dt = mid_time - before_time
Victor Stinner0a01f132011-07-04 18:06:35 +0200283 if dt >= TIMEOUT_HALF:
284 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200285 select.select([read], [], [], TIMEOUT_FULL)
286 after_time = time.time()
287 dt = after_time - mid_time
Victor Stinner0a01f132011-07-04 18:06:35 +0200288 if dt >= TIMEOUT_HALF:
289 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200290 """, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000291
292 def test_wakeup_fd_during(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200293 self.check_wakeup("""def test():
294 import select
295 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000296
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200297 TIMEOUT_FULL = 10
298 TIMEOUT_HALF = 5
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000299
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200300 signal.alarm(1)
301 before_time = time.time()
302 # We attempt to get a signal during the select call
303 try:
304 select.select([read], [], [], TIMEOUT_FULL)
305 except select.error:
306 pass
307 else:
308 raise Exception("select.error not raised")
309 after_time = time.time()
310 dt = after_time - before_time
Victor Stinner0a01f132011-07-04 18:06:35 +0200311 if dt >= TIMEOUT_HALF:
312 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200313 """, signal.SIGALRM)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200314
315 def test_signum(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200316 self.check_wakeup("""def test():
317 signal.signal(signal.SIGUSR1, handler)
318 os.kill(os.getpid(), signal.SIGUSR1)
319 os.kill(os.getpid(), signal.SIGALRM)
320 """, signal.SIGUSR1, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000321
Victor Stinnerc13ef662011-05-25 02:35:58 +0200322 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
323 'need signal.pthread_sigmask()')
Victor Stinnerc13ef662011-05-25 02:35:58 +0200324 def test_pending(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200325 self.check_wakeup("""def test():
326 signum1 = signal.SIGUSR1
327 signum2 = signal.SIGUSR2
Victor Stinnerc13ef662011-05-25 02:35:58 +0200328
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200329 signal.signal(signum1, handler)
330 signal.signal(signum2, handler)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200331
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200332 signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2))
333 os.kill(os.getpid(), signum1)
334 os.kill(os.getpid(), signum2)
335 # Unblocking the 2 signals calls the C signal handler twice
336 signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2))
Charles-François Natali027f9a32011-10-02 18:36:05 +0200337 """, signal.SIGUSR1, signal.SIGUSR2, ordered=False)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200338
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000339
Brian Curtin3f004b12010-08-06 19:34:52 +0000340@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes8640e742008-02-23 16:23:06 +0000341class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000342
Victor Stinnerd6284962011-06-20 23:28:09 +0200343 def readpipe_interrupted(self, interrupt):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000344 """Perform a read during which a signal will arrive. Return True if the
345 read is interrupted by the signal and raises an exception. Return False
346 if it returns normally.
347 """
Victor Stinnerd6284962011-06-20 23:28:09 +0200348 # use a subprocess to have only one thread, to have a timeout on the
349 # blocking read and to not touch signal handling in this process
350 code = """if 1:
351 import errno
352 import os
353 import signal
354 import sys
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000355
Victor Stinnerd6284962011-06-20 23:28:09 +0200356 interrupt = %r
357 r, w = os.pipe()
Christian Heimes8640e742008-02-23 16:23:06 +0000358
Victor Stinnerd6284962011-06-20 23:28:09 +0200359 def handler(signum, frame):
360 pass
361
362 signal.signal(signal.SIGALRM, handler)
363 if interrupt is not None:
364 signal.siginterrupt(signal.SIGALRM, interrupt)
365
Victor Stinnerdfde0d42011-07-01 15:58:39 +0200366 print("ready")
367 sys.stdout.flush()
368
Victor Stinnerd6284962011-06-20 23:28:09 +0200369 # run the test twice
370 for loop in range(2):
371 # send a SIGALRM in a second (during the read)
372 signal.alarm(1)
373 try:
374 # blocking call: read from a pipe without data
375 os.read(r, 1)
376 except OSError as err:
377 if err.errno != errno.EINTR:
378 raise
379 else:
380 sys.exit(2)
381 sys.exit(3)
382 """ % (interrupt,)
383 with spawn_python('-c', code) as process:
Christian Heimes8640e742008-02-23 16:23:06 +0000384 try:
Victor Stinner45273652011-06-22 22:15:51 +0200385 # wait until the child process is loaded and has started
386 first_line = process.stdout.readline()
387
Victor Stinner19e5bcd2011-07-01 15:59:54 +0200388 stdout, stderr = process.communicate(timeout=5.0)
Victor Stinnerd6284962011-06-20 23:28:09 +0200389 except subprocess.TimeoutExpired:
390 process.kill()
Christian Heimes8640e742008-02-23 16:23:06 +0000391 return False
Victor Stinnerd6284962011-06-20 23:28:09 +0200392 else:
Victor Stinner45273652011-06-22 22:15:51 +0200393 stdout = first_line + stdout
Victor Stinnerd6284962011-06-20 23:28:09 +0200394 exitcode = process.wait()
395 if exitcode not in (2, 3):
396 raise Exception("Child error (exit code %s): %s"
397 % (exitcode, stdout))
398 return (exitcode == 3)
Christian Heimes8640e742008-02-23 16:23:06 +0000399
400 def test_without_siginterrupt(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200401 # If a signal handler is installed and siginterrupt is not called
402 # at all, when that signal arrives, it interrupts a syscall that's in
403 # progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200404 interrupted = self.readpipe_interrupted(None)
405 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000406
407 def test_siginterrupt_on(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200408 # If a signal handler is installed and siginterrupt is called with
409 # a true value for the second argument, when that signal arrives, it
410 # interrupts a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200411 interrupted = self.readpipe_interrupted(True)
412 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000413
414 def test_siginterrupt_off(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200415 # If a signal handler is installed and siginterrupt is called with
416 # a false value for the second argument, when that signal arrives, it
417 # does not interrupt a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200418 interrupted = self.readpipe_interrupted(False)
419 self.assertFalse(interrupted)
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000420
421
Brian Curtin3f004b12010-08-06 19:34:52 +0000422@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000423class ItimerTest(unittest.TestCase):
424 def setUp(self):
425 self.hndl_called = False
426 self.hndl_count = 0
427 self.itimer = None
Christian Heimescc47b052008-03-25 14:56:36 +0000428 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000429
430 def tearDown(self):
Christian Heimescc47b052008-03-25 14:56:36 +0000431 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000432 if self.itimer is not None: # test_itimer_exc doesn't change this attr
433 # just ensure that itimer is stopped
434 signal.setitimer(self.itimer, 0)
435
436 def sig_alrm(self, *args):
437 self.hndl_called = True
Martin v. Löwis823725e2008-03-24 13:39:54 +0000438
439 def sig_vtalrm(self, *args):
440 self.hndl_called = True
441
442 if self.hndl_count > 3:
443 # it shouldn't be here, because it should have been disabled.
444 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
445 "timer.")
446 elif self.hndl_count == 3:
447 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
448 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000449
450 self.hndl_count += 1
451
Martin v. Löwis823725e2008-03-24 13:39:54 +0000452 def sig_prof(self, *args):
453 self.hndl_called = True
454 signal.setitimer(signal.ITIMER_PROF, 0)
455
Martin v. Löwis823725e2008-03-24 13:39:54 +0000456 def test_itimer_exc(self):
457 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
458 # defines it ?
459 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Christian Heimescc47b052008-03-25 14:56:36 +0000460 # Negative times are treated as zero on some platforms.
461 if 0:
462 self.assertRaises(signal.ItimerError,
463 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000464
465 def test_itimer_real(self):
466 self.itimer = signal.ITIMER_REAL
Martin v. Löwis823725e2008-03-24 13:39:54 +0000467 signal.setitimer(self.itimer, 1.0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000468 signal.pause()
Martin v. Löwis823725e2008-03-24 13:39:54 +0000469 self.assertEqual(self.hndl_called, True)
470
R. David Murray44546f82010-04-21 01:59:28 +0000471 # Issue 3864, unknown if this affects earlier versions of freebsd also
Gregory P. Smith397cd8a2010-10-17 04:23:21 +0000472 @unittest.skipIf(sys.platform in ('freebsd6', 'netbsd5'),
473 'itimer not reliable (does not mix well with threading) on some BSDs.')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000474 def test_itimer_virtual(self):
475 self.itimer = signal.ITIMER_VIRTUAL
476 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
477 signal.setitimer(self.itimer, 0.3, 0.2)
478
Mark Dickinson78373472009-10-31 10:39:21 +0000479 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000480 while time.time() - start_time < 60.0:
Mark Dickinson95078872009-10-04 18:47:48 +0000481 # use up some virtual time by doing real work
482 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000483 if signal.getitimer(self.itimer) == (0.0, 0.0):
484 break # sig_vtalrm handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000485 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000486 self.skipTest("timeout: likely cause: machine too slow or load too "
487 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000488
489 # virtual itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000490 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Martin v. Löwis823725e2008-03-24 13:39:54 +0000491 # and the handler should have been called
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000492 self.assertEqual(self.hndl_called, True)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000493
R. David Murray44546f82010-04-21 01:59:28 +0000494 # Issue 3864, unknown if this affects earlier versions of freebsd also
495 @unittest.skipIf(sys.platform=='freebsd6',
496 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000497 def test_itimer_prof(self):
498 self.itimer = signal.ITIMER_PROF
499 signal.signal(signal.SIGPROF, self.sig_prof)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000500 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000501
Mark Dickinson78373472009-10-31 10:39:21 +0000502 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000503 while time.time() - start_time < 60.0:
Mark Dickinson78373472009-10-31 10:39:21 +0000504 # do some work
505 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000506 if signal.getitimer(self.itimer) == (0.0, 0.0):
507 break # sig_prof handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000508 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000509 self.skipTest("timeout: likely cause: machine too slow or load too "
510 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000511
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000512 # profiling itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000513 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000514 # and the handler should have been called
Martin v. Löwis823725e2008-03-24 13:39:54 +0000515 self.assertEqual(self.hndl_called, True)
516
Victor Stinnera9293352011-04-30 15:21:58 +0200517
Victor Stinner35b300c2011-05-04 13:20:35 +0200518class PendingSignalsTests(unittest.TestCase):
519 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200520 Test pthread_sigmask(), pthread_kill(), sigpending() and sigwait()
521 functions.
Victor Stinner35b300c2011-05-04 13:20:35 +0200522 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200523 @unittest.skipUnless(hasattr(signal, 'sigpending'),
524 'need signal.sigpending()')
525 def test_sigpending_empty(self):
526 self.assertEqual(signal.sigpending(), set())
527
528 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
529 'need signal.pthread_sigmask()')
530 @unittest.skipUnless(hasattr(signal, 'sigpending'),
531 'need signal.sigpending()')
532 def test_sigpending(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200533 code = """if 1:
534 import os
535 import signal
Victor Stinnerb3e72192011-05-08 01:46:11 +0200536
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200537 def handler(signum, frame):
538 1/0
Victor Stinnerb3e72192011-05-08 01:46:11 +0200539
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200540 signum = signal.SIGUSR1
541 signal.signal(signum, handler)
542
543 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
544 os.kill(os.getpid(), signum)
545 pending = signal.sigpending()
Victor Stinner0a01f132011-07-04 18:06:35 +0200546 if pending != {signum}:
547 raise Exception('%s != {%s}' % (pending, signum))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200548 try:
549 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
550 except ZeroDivisionError:
551 pass
552 else:
553 raise Exception("ZeroDivisionError not raised")
554 """
555 assert_python_ok('-c', code)
Victor Stinnerb3e72192011-05-08 01:46:11 +0200556
557 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
558 'need signal.pthread_kill()')
559 def test_pthread_kill(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200560 code = """if 1:
561 import signal
562 import threading
563 import sys
Victor Stinnerb3e72192011-05-08 01:46:11 +0200564
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200565 signum = signal.SIGUSR1
Victor Stinnerb3e72192011-05-08 01:46:11 +0200566
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200567 def handler(signum, frame):
568 1/0
569
570 signal.signal(signum, handler)
571
572 if sys.platform == 'freebsd6':
573 # Issue #12392 and #12469: send a signal to the main thread
574 # doesn't work before the creation of the first thread on
575 # FreeBSD 6
576 def noop():
577 pass
578 thread = threading.Thread(target=noop)
579 thread.start()
580 thread.join()
581
582 tid = threading.get_ident()
583 try:
584 signal.pthread_kill(tid, signum)
585 except ZeroDivisionError:
586 pass
587 else:
588 raise Exception("ZeroDivisionError not raised")
589 """
590 assert_python_ok('-c', code)
Victor Stinnerb3e72192011-05-08 01:46:11 +0200591
Victor Stinner7f294d12011-06-10 14:02:10 +0200592 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
593 'need signal.pthread_sigmask()')
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200594 def wait_helper(self, blocked, test):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200595 """
596 test: body of the "def test(signum):" function.
597 blocked: number of the blocked signal
598 """
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200599 code = '''if 1:
600 import signal
601 import sys
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200602
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200603 def handler(signum, frame):
604 1/0
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200605
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200606 %s
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200607
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200608 blocked = %s
609 signum = signal.SIGALRM
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200610
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200611 # child: block and wait the signal
612 try:
613 signal.signal(signum, handler)
614 signal.pthread_sigmask(signal.SIG_BLOCK, [blocked])
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200615
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200616 # Do the tests
617 test(signum)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200618
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200619 # The handler must not be called on unblock
620 try:
621 signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked])
622 except ZeroDivisionError:
623 print("the signal handler has been called",
624 file=sys.stderr)
625 sys.exit(1)
626 except BaseException as err:
627 print("error: {}".format(err), file=sys.stderr)
628 sys.stderr.flush()
629 sys.exit(1)
630 ''' % (test.strip(), blocked)
Victor Stinner415007e2011-06-13 16:19:06 +0200631
Ross Lagerwallbc808222011-06-25 12:13:40 +0200632 # sig*wait* must be called with the signal blocked: since the current
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200633 # process might have several threads running, use a subprocess to have
634 # a single thread.
635 assert_python_ok('-c', code)
Victor Stinneraf494602011-06-10 12:48:13 +0200636
Victor Stinnerb3e72192011-05-08 01:46:11 +0200637 @unittest.skipUnless(hasattr(signal, 'sigwait'),
638 'need signal.sigwait()')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200639 def test_sigwait(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200640 self.wait_helper(signal.SIGALRM, '''
641 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200642 signal.alarm(1)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200643 received = signal.sigwait([signum])
Victor Stinner0a01f132011-07-04 18:06:35 +0200644 if received != signum:
645 raise Exception('received %s, not %s' % (received, signum))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200646 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200647
648 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
649 'need signal.sigwaitinfo()')
650 def test_sigwaitinfo(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200651 self.wait_helper(signal.SIGALRM, '''
652 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200653 signal.alarm(1)
654 info = signal.sigwaitinfo([signum])
Victor Stinner0a01f132011-07-04 18:06:35 +0200655 if info.si_signo != signum:
656 raise Exception("info.si_signo != %s" % signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200657 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200658
659 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
660 'need signal.sigtimedwait()')
661 def test_sigtimedwait(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200662 self.wait_helper(signal.SIGALRM, '''
663 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200664 signal.alarm(1)
665 info = signal.sigtimedwait([signum], (10, 1000))
Victor Stinner0a01f132011-07-04 18:06:35 +0200666 if info.si_signo != signum:
667 raise Exception('info.si_signo != %s' % signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200668 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200669
Ross Lagerwallbc808222011-06-25 12:13:40 +0200670 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
671 'need signal.sigtimedwait()')
672 def test_sigtimedwait_poll(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200673 # check that polling with sigtimedwait works
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200674 self.wait_helper(signal.SIGALRM, '''
675 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200676 import os
677 os.kill(os.getpid(), signum)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200678 info = signal.sigtimedwait([signum], (0, 0))
Victor Stinner0a01f132011-07-04 18:06:35 +0200679 if info.si_signo != signum:
680 raise Exception('info.si_signo != %s' % signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200681 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200682
683 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
684 'need signal.sigtimedwait()')
685 def test_sigtimedwait_timeout(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200686 self.wait_helper(signal.SIGALRM, '''
687 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200688 received = signal.sigtimedwait([signum], (1, 0))
Victor Stinner0a01f132011-07-04 18:06:35 +0200689 if received is not None:
690 raise Exception("received=%r" % (received,))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200691 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200692
693 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
694 'need signal.sigtimedwait()')
695 def test_sigtimedwait_negative_timeout(self):
696 signum = signal.SIGALRM
697 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, -1))
698 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (0, -1))
699 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, 0))
700
Ross Lagerwallbc808222011-06-25 12:13:40 +0200701 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
702 'need signal.sigwaitinfo()')
703 def test_sigwaitinfo_interrupted(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200704 self.wait_helper(signal.SIGUSR1, '''
705 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200706 import errno
707
708 hndl_called = True
709 def alarm_handler(signum, frame):
710 hndl_called = False
711
712 signal.signal(signal.SIGALRM, alarm_handler)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200713 signal.alarm(1)
714 try:
715 signal.sigwaitinfo([signal.SIGUSR1])
716 except OSError as e:
717 if e.errno == errno.EINTR:
Victor Stinner0a01f132011-07-04 18:06:35 +0200718 if not hndl_called:
719 raise Exception("SIGALRM handler not called")
Ross Lagerwallbc808222011-06-25 12:13:40 +0200720 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200721 raise Exception("Expected EINTR to be raised by sigwaitinfo")
Ross Lagerwallbc808222011-06-25 12:13:40 +0200722 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200723 raise Exception("Expected EINTR to be raised by sigwaitinfo")
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200724 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200725
726 @unittest.skipUnless(hasattr(signal, 'sigwait'),
727 'need signal.sigwait()')
Victor Stinner415007e2011-06-13 16:19:06 +0200728 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
729 'need signal.pthread_sigmask()')
Victor Stinner10c30d62011-06-10 01:39:53 +0200730 @unittest.skipIf(threading is None, "test needs threading module")
731 def test_sigwait_thread(self):
Victor Stinner415007e2011-06-13 16:19:06 +0200732 # Check that calling sigwait() from a thread doesn't suspend the whole
733 # process. A new interpreter is spawned to avoid problems when mixing
734 # threads and fork(): only async-safe functions are allowed between
735 # fork() and exec().
736 assert_python_ok("-c", """if True:
737 import os, threading, sys, time, signal
Victor Stinner10c30d62011-06-10 01:39:53 +0200738
Victor Stinner415007e2011-06-13 16:19:06 +0200739 # the default handler terminates the process
740 signum = signal.SIGUSR1
741
742 def kill_later():
743 # wait until the main thread is waiting in sigwait()
744 time.sleep(1)
745 os.kill(os.getpid(), signum)
746
747 # the signal must be blocked by all the threads
748 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
749 killer = threading.Thread(target=kill_later)
Victor Stinneraf494602011-06-10 12:48:13 +0200750 killer.start()
751 received = signal.sigwait([signum])
752 if received != signum:
753 print("sigwait() received %s, not %s" % (received, signum),
754 file=sys.stderr)
Victor Stinner415007e2011-06-13 16:19:06 +0200755 sys.exit(1)
Victor Stinner10c30d62011-06-10 01:39:53 +0200756 killer.join()
Victor Stinner415007e2011-06-13 16:19:06 +0200757 # unblock the signal, which should have been cleared by sigwait()
758 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
759 """)
Victor Stinneraf494602011-06-10 12:48:13 +0200760
Victor Stinnerb3e72192011-05-08 01:46:11 +0200761 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
762 'need signal.pthread_sigmask()')
763 def test_pthread_sigmask_arguments(self):
764 self.assertRaises(TypeError, signal.pthread_sigmask)
765 self.assertRaises(TypeError, signal.pthread_sigmask, 1)
766 self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3)
767 self.assertRaises(OSError, signal.pthread_sigmask, 1700, [])
768
769 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
770 'need signal.pthread_sigmask()')
771 def test_pthread_sigmask(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200772 code = """if 1:
773 import signal
774 import os; import threading
775
776 def handler(signum, frame):
777 1/0
778
779 def kill(signum):
780 os.kill(os.getpid(), signum)
781
782 def read_sigmask():
783 return signal.pthread_sigmask(signal.SIG_BLOCK, [])
784
Victor Stinnerb3e72192011-05-08 01:46:11 +0200785 signum = signal.SIGUSR1
Victor Stinner6fd49e12011-05-04 12:38:03 +0200786
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200787 # Install our signal handler
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200788 old_handler = signal.signal(signum, handler)
Victor Stinnera9293352011-04-30 15:21:58 +0200789
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200790 # Unblock SIGUSR1 (and copy the old mask) to test our signal handler
Victor Stinnera9293352011-04-30 15:21:58 +0200791 old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200792 try:
793 kill(signum)
794 except ZeroDivisionError:
795 pass
796 else:
797 raise Exception("ZeroDivisionError not raised")
Victor Stinnera9293352011-04-30 15:21:58 +0200798
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200799 # Block and then raise SIGUSR1. The signal is blocked: the signal
800 # handler is not called, and the signal is now pending
Victor Stinnera9293352011-04-30 15:21:58 +0200801 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200802 kill(signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200803
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200804 # Check the new mask
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200805 blocked = read_sigmask()
Victor Stinner0a01f132011-07-04 18:06:35 +0200806 if signum not in blocked:
807 raise Exception("%s not in %s" % (signum, blocked))
808 if old_mask ^ blocked != {signum}:
809 raise Exception("%s ^ %s != {%s}" % (old_mask, blocked, signum))
Victor Stinnera9293352011-04-30 15:21:58 +0200810
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200811 # Unblock SIGUSR1
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200812 try:
813 # unblock the pending signal calls immediatly the signal handler
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200814 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200815 except ZeroDivisionError:
816 pass
817 else:
818 raise Exception("ZeroDivisionError not raised")
819 try:
820 kill(signum)
821 except ZeroDivisionError:
822 pass
823 else:
824 raise Exception("ZeroDivisionError not raised")
Victor Stinnera9293352011-04-30 15:21:58 +0200825
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200826 # Check the new mask
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200827 unblocked = read_sigmask()
Victor Stinner0a01f132011-07-04 18:06:35 +0200828 if signum in unblocked:
829 raise Exception("%s in %s" % (signum, unblocked))
830 if blocked ^ unblocked != {signum}:
831 raise Exception("%s ^ %s != {%s}" % (blocked, unblocked, signum))
832 if old_mask != unblocked:
833 raise Exception("%s != %s" % (old_mask, unblocked))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200834 """
835 assert_python_ok('-c', code)
836
837 @unittest.skipIf(sys.platform == 'freebsd6',
838 "issue #12392: send a signal to the main thread doesn't work "
839 "before the creation of the first thread on FreeBSD 6")
840 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
841 'need signal.pthread_kill()')
842 def test_pthread_kill_main_thread(self):
843 # Test that a signal can be sent to the main thread with pthread_kill()
844 # before any other thread has been created (see issue #12392).
845 code = """if True:
846 import threading
847 import signal
848 import sys
849
850 def handler(signum, frame):
851 sys.exit(3)
852
853 signal.signal(signal.SIGUSR1, handler)
854 signal.pthread_kill(threading.get_ident(), signal.SIGUSR1)
855 sys.exit(2)
856 """
857
858 with spawn_python('-c', code) as process:
859 stdout, stderr = process.communicate()
860 exitcode = process.wait()
861 if exitcode != 3:
862 raise Exception("Child error (exit code %s): %s" %
863 (exitcode, stdout))
Victor Stinnera9293352011-04-30 15:21:58 +0200864
865
Thomas Woutersed03b412007-08-28 21:37:11 +0000866def test_main():
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100867 try:
Victor Stinnerb3e72192011-05-08 01:46:11 +0200868 support.run_unittest(PosixTests, InterProcessSignalTests,
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100869 WakeupSignalTests, SiginterruptTest,
Victor Stinnera9293352011-04-30 15:21:58 +0200870 ItimerTest, WindowsSignalTests,
Victor Stinner35b300c2011-05-04 13:20:35 +0200871 PendingSignalsTests)
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100872 finally:
873 support.reap_children()
Thomas Woutersed03b412007-08-28 21:37:11 +0000874
875
876if __name__ == "__main__":
877 test_main()