blob: c349252dbc0780dd10f0c10227a058ac56a2654c [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):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200227 def check_wakeup(self, test_body, *signals):
228 # 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)
Victor Stinner0a01f132011-07-04 18:06:35 +0200243 if raised != signals:
244 raise Exception("%r != %r" % (raised, signals))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200245
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200246 {}
247
248 signal.signal(signal.SIGALRM, handler)
249 read, write = os.pipe()
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200250 for fd in (read, write):
251 flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
252 flags = flags | os.O_NONBLOCK
253 fcntl.fcntl(fd, fcntl.F_SETFL, flags)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200254 signal.set_wakeup_fd(write)
255
256 test()
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200257 check_signum(signals)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200258
259 os.close(read)
260 os.close(write)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200261 """.format(signals, test_body)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200262
263 assert_python_ok('-c', code)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200264
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000265 def test_wakeup_fd_early(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200266 self.check_wakeup("""def test():
267 import select
268 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000269
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200270 TIMEOUT_FULL = 10
271 TIMEOUT_HALF = 5
272
273 signal.alarm(1)
274 before_time = time.time()
275 # We attempt to get a signal during the sleep,
276 # before select is called
277 time.sleep(TIMEOUT_FULL)
278 mid_time = time.time()
279 dt = mid_time - before_time
Victor Stinner0a01f132011-07-04 18:06:35 +0200280 if dt >= TIMEOUT_HALF:
281 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200282 select.select([read], [], [], TIMEOUT_FULL)
283 after_time = time.time()
284 dt = after_time - mid_time
Victor Stinner0a01f132011-07-04 18:06:35 +0200285 if dt >= TIMEOUT_HALF:
286 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200287 """, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000288
289 def test_wakeup_fd_during(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200290 self.check_wakeup("""def test():
291 import select
292 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000293
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200294 TIMEOUT_FULL = 10
295 TIMEOUT_HALF = 5
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000296
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200297 signal.alarm(1)
298 before_time = time.time()
299 # We attempt to get a signal during the select call
300 try:
301 select.select([read], [], [], TIMEOUT_FULL)
302 except select.error:
303 pass
304 else:
305 raise Exception("select.error not raised")
306 after_time = time.time()
307 dt = after_time - before_time
Victor Stinner0a01f132011-07-04 18:06:35 +0200308 if dt >= TIMEOUT_HALF:
309 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200310 """, signal.SIGALRM)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200311
312 def test_signum(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200313 self.check_wakeup("""def test():
314 signal.signal(signal.SIGUSR1, handler)
315 os.kill(os.getpid(), signal.SIGUSR1)
316 os.kill(os.getpid(), signal.SIGALRM)
317 """, signal.SIGUSR1, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000318
Victor Stinnerc13ef662011-05-25 02:35:58 +0200319 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
320 'need signal.pthread_sigmask()')
Victor Stinnerc13ef662011-05-25 02:35:58 +0200321 def test_pending(self):
Victor Stinner5dd470e2011-07-05 01:32:06 +0200322 signals = (signal.SIGUSR1, signal.SIGUSR2)
323 # when signals are unblocked, pending signal ared delivered in the
324 # reverse order of their number
325 signals = tuple(sorted(signals, reverse=True))
326
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200327 self.check_wakeup("""def test():
328 signum1 = signal.SIGUSR1
329 signum2 = signal.SIGUSR2
Victor Stinnerc13ef662011-05-25 02:35:58 +0200330
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200331 signal.signal(signum1, handler)
332 signal.signal(signum2, handler)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200333
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200334 signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2))
335 os.kill(os.getpid(), signum1)
336 os.kill(os.getpid(), signum2)
337 # Unblocking the 2 signals calls the C signal handler twice
338 signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2))
Victor Stinner5dd470e2011-07-05 01:32:06 +0200339 """, *signals)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200340
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000341
Brian Curtin3f004b12010-08-06 19:34:52 +0000342@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes8640e742008-02-23 16:23:06 +0000343class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000344
Victor Stinnerd6284962011-06-20 23:28:09 +0200345 def readpipe_interrupted(self, interrupt):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000346 """Perform a read during which a signal will arrive. Return True if the
347 read is interrupted by the signal and raises an exception. Return False
348 if it returns normally.
349 """
Victor Stinnerd6284962011-06-20 23:28:09 +0200350 # use a subprocess to have only one thread, to have a timeout on the
351 # blocking read and to not touch signal handling in this process
352 code = """if 1:
353 import errno
354 import os
355 import signal
356 import sys
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000357
Victor Stinnerd6284962011-06-20 23:28:09 +0200358 interrupt = %r
359 r, w = os.pipe()
Christian Heimes8640e742008-02-23 16:23:06 +0000360
Victor Stinnerd6284962011-06-20 23:28:09 +0200361 def handler(signum, frame):
362 pass
363
364 signal.signal(signal.SIGALRM, handler)
365 if interrupt is not None:
366 signal.siginterrupt(signal.SIGALRM, interrupt)
367
Victor Stinnerdfde0d42011-07-01 15:58:39 +0200368 print("ready")
369 sys.stdout.flush()
370
Victor Stinnerd6284962011-06-20 23:28:09 +0200371 # run the test twice
372 for loop in range(2):
373 # send a SIGALRM in a second (during the read)
374 signal.alarm(1)
375 try:
376 # blocking call: read from a pipe without data
377 os.read(r, 1)
378 except OSError as err:
379 if err.errno != errno.EINTR:
380 raise
381 else:
382 sys.exit(2)
383 sys.exit(3)
384 """ % (interrupt,)
385 with spawn_python('-c', code) as process:
Christian Heimes8640e742008-02-23 16:23:06 +0000386 try:
Victor Stinner45273652011-06-22 22:15:51 +0200387 # wait until the child process is loaded and has started
388 first_line = process.stdout.readline()
389
Victor Stinner19e5bcd2011-07-01 15:59:54 +0200390 stdout, stderr = process.communicate(timeout=5.0)
Victor Stinnerd6284962011-06-20 23:28:09 +0200391 except subprocess.TimeoutExpired:
392 process.kill()
Christian Heimes8640e742008-02-23 16:23:06 +0000393 return False
Victor Stinnerd6284962011-06-20 23:28:09 +0200394 else:
Victor Stinner45273652011-06-22 22:15:51 +0200395 stdout = first_line + stdout
Victor Stinnerd6284962011-06-20 23:28:09 +0200396 exitcode = process.wait()
397 if exitcode not in (2, 3):
398 raise Exception("Child error (exit code %s): %s"
399 % (exitcode, stdout))
400 return (exitcode == 3)
Christian Heimes8640e742008-02-23 16:23:06 +0000401
402 def test_without_siginterrupt(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200403 # If a signal handler is installed and siginterrupt is not called
404 # at all, when that signal arrives, it interrupts a syscall that's in
405 # progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200406 interrupted = self.readpipe_interrupted(None)
407 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000408
409 def test_siginterrupt_on(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200410 # If a signal handler is installed and siginterrupt is called with
411 # a true value for the second argument, when that signal arrives, it
412 # interrupts a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200413 interrupted = self.readpipe_interrupted(True)
414 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000415
416 def test_siginterrupt_off(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200417 # If a signal handler is installed and siginterrupt is called with
418 # a false value for the second argument, when that signal arrives, it
419 # does not interrupt a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200420 interrupted = self.readpipe_interrupted(False)
421 self.assertFalse(interrupted)
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000422
423
Brian Curtin3f004b12010-08-06 19:34:52 +0000424@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000425class ItimerTest(unittest.TestCase):
426 def setUp(self):
427 self.hndl_called = False
428 self.hndl_count = 0
429 self.itimer = None
Christian Heimescc47b052008-03-25 14:56:36 +0000430 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000431
432 def tearDown(self):
Christian Heimescc47b052008-03-25 14:56:36 +0000433 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000434 if self.itimer is not None: # test_itimer_exc doesn't change this attr
435 # just ensure that itimer is stopped
436 signal.setitimer(self.itimer, 0)
437
438 def sig_alrm(self, *args):
439 self.hndl_called = True
Martin v. Löwis823725e2008-03-24 13:39:54 +0000440
441 def sig_vtalrm(self, *args):
442 self.hndl_called = True
443
444 if self.hndl_count > 3:
445 # it shouldn't be here, because it should have been disabled.
446 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
447 "timer.")
448 elif self.hndl_count == 3:
449 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
450 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000451
452 self.hndl_count += 1
453
Martin v. Löwis823725e2008-03-24 13:39:54 +0000454 def sig_prof(self, *args):
455 self.hndl_called = True
456 signal.setitimer(signal.ITIMER_PROF, 0)
457
Martin v. Löwis823725e2008-03-24 13:39:54 +0000458 def test_itimer_exc(self):
459 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
460 # defines it ?
461 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Christian Heimescc47b052008-03-25 14:56:36 +0000462 # Negative times are treated as zero on some platforms.
463 if 0:
464 self.assertRaises(signal.ItimerError,
465 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000466
467 def test_itimer_real(self):
468 self.itimer = signal.ITIMER_REAL
Martin v. Löwis823725e2008-03-24 13:39:54 +0000469 signal.setitimer(self.itimer, 1.0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000470 signal.pause()
Martin v. Löwis823725e2008-03-24 13:39:54 +0000471 self.assertEqual(self.hndl_called, True)
472
R. David Murray44546f82010-04-21 01:59:28 +0000473 # Issue 3864, unknown if this affects earlier versions of freebsd also
Gregory P. Smith397cd8a2010-10-17 04:23:21 +0000474 @unittest.skipIf(sys.platform in ('freebsd6', 'netbsd5'),
475 'itimer not reliable (does not mix well with threading) on some BSDs.')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000476 def test_itimer_virtual(self):
477 self.itimer = signal.ITIMER_VIRTUAL
478 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
479 signal.setitimer(self.itimer, 0.3, 0.2)
480
Mark Dickinson78373472009-10-31 10:39:21 +0000481 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000482 while time.time() - start_time < 60.0:
Mark Dickinson95078872009-10-04 18:47:48 +0000483 # use up some virtual time by doing real work
484 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000485 if signal.getitimer(self.itimer) == (0.0, 0.0):
486 break # sig_vtalrm handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000487 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000488 self.skipTest("timeout: likely cause: machine too slow or load too "
489 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000490
491 # virtual itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000492 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Martin v. Löwis823725e2008-03-24 13:39:54 +0000493 # and the handler should have been called
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000494 self.assertEqual(self.hndl_called, True)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000495
R. David Murray44546f82010-04-21 01:59:28 +0000496 # Issue 3864, unknown if this affects earlier versions of freebsd also
497 @unittest.skipIf(sys.platform=='freebsd6',
498 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000499 def test_itimer_prof(self):
500 self.itimer = signal.ITIMER_PROF
501 signal.signal(signal.SIGPROF, self.sig_prof)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000502 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000503
Mark Dickinson78373472009-10-31 10:39:21 +0000504 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000505 while time.time() - start_time < 60.0:
Mark Dickinson78373472009-10-31 10:39:21 +0000506 # do some work
507 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000508 if signal.getitimer(self.itimer) == (0.0, 0.0):
509 break # sig_prof handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000510 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000511 self.skipTest("timeout: likely cause: machine too slow or load too "
512 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000513
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000514 # profiling itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000515 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000516 # and the handler should have been called
Martin v. Löwis823725e2008-03-24 13:39:54 +0000517 self.assertEqual(self.hndl_called, True)
518
Victor Stinnera9293352011-04-30 15:21:58 +0200519
Victor Stinner35b300c2011-05-04 13:20:35 +0200520class PendingSignalsTests(unittest.TestCase):
521 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200522 Test pthread_sigmask(), pthread_kill(), sigpending() and sigwait()
523 functions.
Victor Stinner35b300c2011-05-04 13:20:35 +0200524 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200525 @unittest.skipUnless(hasattr(signal, 'sigpending'),
526 'need signal.sigpending()')
527 def test_sigpending_empty(self):
528 self.assertEqual(signal.sigpending(), set())
529
530 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
531 'need signal.pthread_sigmask()')
532 @unittest.skipUnless(hasattr(signal, 'sigpending'),
533 'need signal.sigpending()')
534 def test_sigpending(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200535 code = """if 1:
536 import os
537 import signal
Victor Stinnerb3e72192011-05-08 01:46:11 +0200538
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200539 def handler(signum, frame):
540 1/0
Victor Stinnerb3e72192011-05-08 01:46:11 +0200541
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200542 signum = signal.SIGUSR1
543 signal.signal(signum, handler)
544
545 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
546 os.kill(os.getpid(), signum)
547 pending = signal.sigpending()
Victor Stinner0a01f132011-07-04 18:06:35 +0200548 if pending != {signum}:
549 raise Exception('%s != {%s}' % (pending, signum))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200550 try:
551 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
552 except ZeroDivisionError:
553 pass
554 else:
555 raise Exception("ZeroDivisionError not raised")
556 """
557 assert_python_ok('-c', code)
Victor Stinnerb3e72192011-05-08 01:46:11 +0200558
559 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
560 'need signal.pthread_kill()')
561 def test_pthread_kill(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200562 code = """if 1:
563 import signal
564 import threading
565 import sys
Victor Stinnerb3e72192011-05-08 01:46:11 +0200566
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200567 signum = signal.SIGUSR1
Victor Stinnerb3e72192011-05-08 01:46:11 +0200568
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200569 def handler(signum, frame):
570 1/0
571
572 signal.signal(signum, handler)
573
574 if sys.platform == 'freebsd6':
575 # Issue #12392 and #12469: send a signal to the main thread
576 # doesn't work before the creation of the first thread on
577 # FreeBSD 6
578 def noop():
579 pass
580 thread = threading.Thread(target=noop)
581 thread.start()
582 thread.join()
583
584 tid = threading.get_ident()
585 try:
586 signal.pthread_kill(tid, signum)
587 except ZeroDivisionError:
588 pass
589 else:
590 raise Exception("ZeroDivisionError not raised")
591 """
592 assert_python_ok('-c', code)
Victor Stinnerb3e72192011-05-08 01:46:11 +0200593
Victor Stinner7f294d12011-06-10 14:02:10 +0200594 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
595 'need signal.pthread_sigmask()')
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200596 def wait_helper(self, blocked, test):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200597 """
598 test: body of the "def test(signum):" function.
599 blocked: number of the blocked signal
600 """
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200601 code = '''if 1:
602 import signal
603 import sys
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200604
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200605 def handler(signum, frame):
606 1/0
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200607
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200608 %s
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200609
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200610 blocked = %s
611 signum = signal.SIGALRM
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200612
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200613 # child: block and wait the signal
614 try:
615 signal.signal(signum, handler)
616 signal.pthread_sigmask(signal.SIG_BLOCK, [blocked])
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200617
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200618 # Do the tests
619 test(signum)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200620
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200621 # The handler must not be called on unblock
622 try:
623 signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked])
624 except ZeroDivisionError:
625 print("the signal handler has been called",
626 file=sys.stderr)
627 sys.exit(1)
628 except BaseException as err:
629 print("error: {}".format(err), file=sys.stderr)
630 sys.stderr.flush()
631 sys.exit(1)
632 ''' % (test.strip(), blocked)
Victor Stinner415007e2011-06-13 16:19:06 +0200633
Ross Lagerwallbc808222011-06-25 12:13:40 +0200634 # sig*wait* must be called with the signal blocked: since the current
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200635 # process might have several threads running, use a subprocess to have
636 # a single thread.
637 assert_python_ok('-c', code)
Victor Stinneraf494602011-06-10 12:48:13 +0200638
Victor Stinnerb3e72192011-05-08 01:46:11 +0200639 @unittest.skipUnless(hasattr(signal, 'sigwait'),
640 'need signal.sigwait()')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200641 def test_sigwait(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200642 self.wait_helper(signal.SIGALRM, '''
643 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200644 signal.alarm(1)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200645 received = signal.sigwait([signum])
Victor Stinner0a01f132011-07-04 18:06:35 +0200646 if received != signum:
647 raise Exception('received %s, not %s' % (received, signum))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200648 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200649
650 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
651 'need signal.sigwaitinfo()')
652 def test_sigwaitinfo(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200653 self.wait_helper(signal.SIGALRM, '''
654 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200655 signal.alarm(1)
656 info = signal.sigwaitinfo([signum])
Victor Stinner0a01f132011-07-04 18:06:35 +0200657 if info.si_signo != signum:
658 raise Exception("info.si_signo != %s" % signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200659 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200660
661 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
662 'need signal.sigtimedwait()')
663 def test_sigtimedwait(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200664 self.wait_helper(signal.SIGALRM, '''
665 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200666 signal.alarm(1)
667 info = signal.sigtimedwait([signum], (10, 1000))
Victor Stinner0a01f132011-07-04 18:06:35 +0200668 if info.si_signo != signum:
669 raise Exception('info.si_signo != %s' % signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200670 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200671
Ross Lagerwallbc808222011-06-25 12:13:40 +0200672 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
673 'need signal.sigtimedwait()')
674 def test_sigtimedwait_poll(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200675 # check that polling with sigtimedwait works
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200676 self.wait_helper(signal.SIGALRM, '''
677 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200678 import os
679 os.kill(os.getpid(), signum)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200680 info = signal.sigtimedwait([signum], (0, 0))
Victor Stinner0a01f132011-07-04 18:06:35 +0200681 if info.si_signo != signum:
682 raise Exception('info.si_signo != %s' % signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200683 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200684
685 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
686 'need signal.sigtimedwait()')
687 def test_sigtimedwait_timeout(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200688 self.wait_helper(signal.SIGALRM, '''
689 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200690 received = signal.sigtimedwait([signum], (1, 0))
Victor Stinner0a01f132011-07-04 18:06:35 +0200691 if received is not None:
692 raise Exception("received=%r" % (received,))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200693 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200694
695 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
696 'need signal.sigtimedwait()')
697 def test_sigtimedwait_negative_timeout(self):
698 signum = signal.SIGALRM
699 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, -1))
700 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (0, -1))
701 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, 0))
702
Ross Lagerwallbc808222011-06-25 12:13:40 +0200703 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
704 'need signal.sigwaitinfo()')
705 def test_sigwaitinfo_interrupted(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200706 self.wait_helper(signal.SIGUSR1, '''
707 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200708 import errno
709
710 hndl_called = True
711 def alarm_handler(signum, frame):
712 hndl_called = False
713
714 signal.signal(signal.SIGALRM, alarm_handler)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200715 signal.alarm(1)
716 try:
717 signal.sigwaitinfo([signal.SIGUSR1])
718 except OSError as e:
719 if e.errno == errno.EINTR:
Victor Stinner0a01f132011-07-04 18:06:35 +0200720 if not hndl_called:
721 raise Exception("SIGALRM handler not called")
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")
Ross Lagerwallbc808222011-06-25 12:13:40 +0200724 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200725 raise Exception("Expected EINTR to be raised by sigwaitinfo")
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200726 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200727
728 @unittest.skipUnless(hasattr(signal, 'sigwait'),
729 'need signal.sigwait()')
Victor Stinner415007e2011-06-13 16:19:06 +0200730 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
731 'need signal.pthread_sigmask()')
Victor Stinner10c30d62011-06-10 01:39:53 +0200732 @unittest.skipIf(threading is None, "test needs threading module")
733 def test_sigwait_thread(self):
Victor Stinner415007e2011-06-13 16:19:06 +0200734 # Check that calling sigwait() from a thread doesn't suspend the whole
735 # process. A new interpreter is spawned to avoid problems when mixing
736 # threads and fork(): only async-safe functions are allowed between
737 # fork() and exec().
738 assert_python_ok("-c", """if True:
739 import os, threading, sys, time, signal
Victor Stinner10c30d62011-06-10 01:39:53 +0200740
Victor Stinner415007e2011-06-13 16:19:06 +0200741 # the default handler terminates the process
742 signum = signal.SIGUSR1
743
744 def kill_later():
745 # wait until the main thread is waiting in sigwait()
746 time.sleep(1)
747 os.kill(os.getpid(), signum)
748
749 # the signal must be blocked by all the threads
750 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
751 killer = threading.Thread(target=kill_later)
Victor Stinneraf494602011-06-10 12:48:13 +0200752 killer.start()
753 received = signal.sigwait([signum])
754 if received != signum:
755 print("sigwait() received %s, not %s" % (received, signum),
756 file=sys.stderr)
Victor Stinner415007e2011-06-13 16:19:06 +0200757 sys.exit(1)
Victor Stinner10c30d62011-06-10 01:39:53 +0200758 killer.join()
Victor Stinner415007e2011-06-13 16:19:06 +0200759 # unblock the signal, which should have been cleared by sigwait()
760 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
761 """)
Victor Stinneraf494602011-06-10 12:48:13 +0200762
Victor Stinnerb3e72192011-05-08 01:46:11 +0200763 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
764 'need signal.pthread_sigmask()')
765 def test_pthread_sigmask_arguments(self):
766 self.assertRaises(TypeError, signal.pthread_sigmask)
767 self.assertRaises(TypeError, signal.pthread_sigmask, 1)
768 self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3)
769 self.assertRaises(OSError, signal.pthread_sigmask, 1700, [])
770
771 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
772 'need signal.pthread_sigmask()')
773 def test_pthread_sigmask(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200774 code = """if 1:
775 import signal
776 import os; import threading
777
778 def handler(signum, frame):
779 1/0
780
781 def kill(signum):
782 os.kill(os.getpid(), signum)
783
784 def read_sigmask():
785 return signal.pthread_sigmask(signal.SIG_BLOCK, [])
786
Victor Stinnerb3e72192011-05-08 01:46:11 +0200787 signum = signal.SIGUSR1
Victor Stinner6fd49e12011-05-04 12:38:03 +0200788
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200789 # Install our signal handler
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200790 old_handler = signal.signal(signum, handler)
Victor Stinnera9293352011-04-30 15:21:58 +0200791
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200792 # Unblock SIGUSR1 (and copy the old mask) to test our signal handler
Victor Stinnera9293352011-04-30 15:21:58 +0200793 old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200794 try:
795 kill(signum)
796 except ZeroDivisionError:
797 pass
798 else:
799 raise Exception("ZeroDivisionError not raised")
Victor Stinnera9293352011-04-30 15:21:58 +0200800
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200801 # Block and then raise SIGUSR1. The signal is blocked: the signal
802 # handler is not called, and the signal is now pending
Victor Stinnera9293352011-04-30 15:21:58 +0200803 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200804 kill(signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200805
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200806 # Check the new mask
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200807 blocked = read_sigmask()
Victor Stinner0a01f132011-07-04 18:06:35 +0200808 if signum not in blocked:
809 raise Exception("%s not in %s" % (signum, blocked))
810 if old_mask ^ blocked != {signum}:
811 raise Exception("%s ^ %s != {%s}" % (old_mask, blocked, signum))
Victor Stinnera9293352011-04-30 15:21:58 +0200812
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200813 # Unblock SIGUSR1
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200814 try:
815 # unblock the pending signal calls immediatly the signal handler
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200816 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200817 except ZeroDivisionError:
818 pass
819 else:
820 raise Exception("ZeroDivisionError not raised")
821 try:
822 kill(signum)
823 except ZeroDivisionError:
824 pass
825 else:
826 raise Exception("ZeroDivisionError not raised")
Victor Stinnera9293352011-04-30 15:21:58 +0200827
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200828 # Check the new mask
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200829 unblocked = read_sigmask()
Victor Stinner0a01f132011-07-04 18:06:35 +0200830 if signum in unblocked:
831 raise Exception("%s in %s" % (signum, unblocked))
832 if blocked ^ unblocked != {signum}:
833 raise Exception("%s ^ %s != {%s}" % (blocked, unblocked, signum))
834 if old_mask != unblocked:
835 raise Exception("%s != %s" % (old_mask, unblocked))
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200836 """
837 assert_python_ok('-c', code)
838
839 @unittest.skipIf(sys.platform == 'freebsd6',
840 "issue #12392: send a signal to the main thread doesn't work "
841 "before the creation of the first thread on FreeBSD 6")
842 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
843 'need signal.pthread_kill()')
844 def test_pthread_kill_main_thread(self):
845 # Test that a signal can be sent to the main thread with pthread_kill()
846 # before any other thread has been created (see issue #12392).
847 code = """if True:
848 import threading
849 import signal
850 import sys
851
852 def handler(signum, frame):
853 sys.exit(3)
854
855 signal.signal(signal.SIGUSR1, handler)
856 signal.pthread_kill(threading.get_ident(), signal.SIGUSR1)
857 sys.exit(2)
858 """
859
860 with spawn_python('-c', code) as process:
861 stdout, stderr = process.communicate()
862 exitcode = process.wait()
863 if exitcode != 3:
864 raise Exception("Child error (exit code %s): %s" %
865 (exitcode, stdout))
Victor Stinnera9293352011-04-30 15:21:58 +0200866
867
Thomas Woutersed03b412007-08-28 21:37:11 +0000868def test_main():
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100869 try:
Victor Stinnerb3e72192011-05-08 01:46:11 +0200870 support.run_unittest(PosixTests, InterProcessSignalTests,
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100871 WakeupSignalTests, SiginterruptTest,
Victor Stinnera9293352011-04-30 15:21:58 +0200872 ItimerTest, WindowsSignalTests,
Victor Stinner35b300c2011-05-04 13:20:35 +0200873 PendingSignalsTests)
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100874 finally:
875 support.reap_children()
Thomas Woutersed03b412007-08-28 21:37:11 +0000876
877
878if __name__ == "__main__":
879 test_main()