@@ -32,39 +32,28 @@ def handle_signals(sig,frame):
32
32
33
33
# a function that will be spawned as a separate thread.
34
34
def send_signals ():
35
- os .kill (process_pid , signal .SIGUSR1 )
36
- os .kill (process_pid , signal .SIGUSR2 )
35
+ # We use `raise_signal` rather than `kill` because:
36
+ # * It verifies that a signal delivered to a background thread still has
37
+ # its Python-level handler called on the main thread.
38
+ # * It ensures the signal is handled before the thread exits.
39
+ signal .raise_signal (signal .SIGUSR1 )
40
+ signal .raise_signal (signal .SIGUSR2 )
37
41
signalled_all .release ()
38
42
39
43
40
44
@threading_helper .requires_working_threading ()
41
- @unittest .skipUnless (hasattr (signal , "alarm" ), "test requires signal.alarm" )
42
45
class ThreadSignals (unittest .TestCase ):
43
46
44
47
def test_signals (self ):
45
48
with threading_helper .wait_threads_exit ():
46
49
# Test signal handling semantics of threads.
47
- # We spawn a thread, have the thread send two signals, and
50
+ # We spawn a thread, have the thread send itself two signals, and
48
51
# wait for it to finish. Check that we got both signals
49
52
# and that they were run by the main thread.
50
53
signalled_all .acquire ()
51
54
self .spawnSignallingThread ()
52
55
signalled_all .acquire ()
53
56
54
- # the signals that we asked the kernel to send
55
- # will come back, but we don't know when.
56
- # (it might even be after the thread exits
57
- # and might be out of order.) If we haven't seen
58
- # the signals yet, send yet another signal and
59
- # wait for it return.
60
- if signal_blackboard [signal .SIGUSR1 ]['tripped' ] == 0 \
61
- or signal_blackboard [signal .SIGUSR2 ]['tripped' ] == 0 :
62
- try :
63
- signal .alarm (1 )
64
- signal .pause ()
65
- finally :
66
- signal .alarm (0 )
67
-
68
57
self .assertEqual ( signal_blackboard [signal .SIGUSR1 ]['tripped' ], 1 )
69
58
self .assertEqual ( signal_blackboard [signal .SIGUSR1 ]['tripped_by' ],
70
59
thread .get_ident ())
0 commit comments