blob: 7959e917eb323864b9df591c1d1ddf26a93f7b59 [file] [log] [blame]
Michael W. Hudson43220ea2004-08-03 14:37:14 +00001"""PyUnit testing that threads honor our signal semantics"""
2
3import unittest
Georg Brandl2067bfd2008-05-25 13:05:15 +00004import _thread as thread
Michael W. Hudson43220ea2004-08-03 14:37:14 +00005import signal
6import os
Fred Drake48187482004-08-03 16:14:13 +00007import sys
Benjamin Petersone549ead2009-03-28 21:42:05 +00008from test.support import run_unittest
Michael W. Hudson43220ea2004-08-03 14:37:14 +00009
Benjamin Petersone549ead2009-03-28 21:42:05 +000010if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos':
11 raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
Michael W. Hudson34fba3b2004-08-03 15:35:29 +000012
Michael W. Hudson43220ea2004-08-03 14:37:14 +000013process_pid = os.getpid()
14signalled_all=thread.allocate_lock()
15
16
Guido van Rossum1bc535d2007-05-15 18:46:22 +000017def registerSignals(for_usr1, for_usr2, for_alrm):
Michael W. Hudson43220ea2004-08-03 14:37:14 +000018 usr1 = signal.signal(signal.SIGUSR1, for_usr1)
19 usr2 = signal.signal(signal.SIGUSR2, for_usr2)
20 alrm = signal.signal(signal.SIGALRM, for_alrm)
21 return usr1, usr2, alrm
22
23
Fred Drakedb390c12005-10-28 14:39:47 +000024# The signal handler. Just note that the signal occurred and
Michael W. Hudson43220ea2004-08-03 14:37:14 +000025# from who.
26def handle_signals(sig,frame):
Tim Peters6db15d72004-08-04 02:36:18 +000027 signal_blackboard[sig]['tripped'] += 1
Michael W. Hudson43220ea2004-08-03 14:37:14 +000028 signal_blackboard[sig]['tripped_by'] = thread.get_ident()
29
30# a function that will be spawned as a separate thread.
31def send_signals():
32 os.kill(process_pid, signal.SIGUSR1)
33 os.kill(process_pid, signal.SIGUSR2)
34 signalled_all.release()
35
36class ThreadSignals(unittest.TestCase):
37 """Test signal handling semantics of threads.
38 We spawn a thread, have the thread send two signals, and
39 wait for it to finish. Check that we got both signals
40 and that they were run by the main thread.
41 """
42 def test_signals(self):
43 signalled_all.acquire()
44 self.spawnSignallingThread()
45 signalled_all.acquire()
46 # the signals that we asked the kernel to send
47 # will come back, but we don't know when.
48 # (it might even be after the thread exits
49 # and might be out of order.) If we haven't seen
50 # the signals yet, send yet another signal and
51 # wait for it return.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000052 if signal_blackboard[signal.SIGUSR1]['tripped'] == 0 \
Michael W. Hudson43220ea2004-08-03 14:37:14 +000053 or signal_blackboard[signal.SIGUSR2]['tripped'] == 0:
Tim Peters6db15d72004-08-04 02:36:18 +000054 signal.alarm(1)
55 signal.pause()
56 signal.alarm(0)
Michael W. Hudson43220ea2004-08-03 14:37:14 +000057
58 self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped'], 1)
Tim Peters6db15d72004-08-04 02:36:18 +000059 self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped_by'],
Michael W. Hudson43220ea2004-08-03 14:37:14 +000060 thread.get_ident())
61 self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped'], 1)
Tim Peters6db15d72004-08-04 02:36:18 +000062 self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped_by'],
Michael W. Hudson43220ea2004-08-03 14:37:14 +000063 thread.get_ident())
Michael W. Hudson574a2512004-08-04 14:22:56 +000064 signalled_all.release()
Michael W. Hudson43220ea2004-08-03 14:37:14 +000065
66 def spawnSignallingThread(self):
67 thread.start_new_thread(send_signals, ())
Tim Peters6db15d72004-08-04 02:36:18 +000068
Michael W. Hudson43220ea2004-08-03 14:37:14 +000069
70def test_main():
Michael W. Hudson574a2512004-08-04 14:22:56 +000071 global signal_blackboard
Tim Petersd1b78272004-08-07 06:03:09 +000072
Michael W. Hudson574a2512004-08-04 14:22:56 +000073 signal_blackboard = { signal.SIGUSR1 : {'tripped': 0, 'tripped_by': 0 },
74 signal.SIGUSR2 : {'tripped': 0, 'tripped_by': 0 },
75 signal.SIGALRM : {'tripped': 0, 'tripped_by': 0 } }
76
Guido van Rossum1bc535d2007-05-15 18:46:22 +000077 oldsigs = registerSignals(handle_signals, handle_signals, handle_signals)
Michael W. Hudson43220ea2004-08-03 14:37:14 +000078 try:
Michael W. Hudson574a2512004-08-04 14:22:56 +000079 run_unittest(ThreadSignals)
Michael W. Hudson43220ea2004-08-03 14:37:14 +000080 finally:
Guido van Rossum1bc535d2007-05-15 18:46:22 +000081 registerSignals(*oldsigs)
Michael W. Hudson43220ea2004-08-03 14:37:14 +000082
83if __name__ == '__main__':
84 test_main()