Adjust calling of Perl_va_copy(), noticed by Jarkko
[p5sagit/p5-mst-13.2.git] / ext / threads / t / kill.t
CommitLineData
c0003851 1use strict;
2use warnings;
3
4BEGIN {
5 if ($ENV{'PERL_CORE'}){
6 chdir 't';
7 unshift @INC, '../lib';
8 }
9 use Config;
10 if (! $Config{'useithreads'}) {
11 print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
12 exit(0);
13 }
14}
15
16use ExtUtils::testlib;
17
18use threads;
19use threads::shared;
20
21{
22 package Thread::Semaphore;
23 use threads::shared;
24
25 sub new {
26 my $class = shift;
27 my $val : shared = @_ ? shift : 1;
28 bless \$val, $class;
29 }
30
31 sub down {
32 my $s = shift;
33 lock($$s);
34 my $inc = @_ ? shift : 1;
35 cond_wait $$s until $$s >= $inc;
36 $$s -= $inc;
37 }
38
39 sub up {
40 my $s = shift;
41 lock($$s);
42 my $inc = @_ ? shift : 1;
43 ($$s += $inc) > 0 and cond_broadcast $$s;
44 }
45}
46
47BEGIN {
48 $| = 1;
49 print("1..18\n"); ### Number of tests that will be run ###
50};
51
52my $TEST = 1;
53share($TEST);
54
55ok(1, 'Loaded');
56
57sub ok {
58 my ($ok, $name) = @_;
59
60 lock($TEST);
61 my $id = $TEST++;
62
63 # You have to do it this way or VMS will get confused.
64 if ($ok) {
65 print("ok $id - $name\n");
66 } else {
67 print("not ok $id - $name\n");
68 printf("# Failed test at line %d\n", (caller)[2]);
69 }
70
71 return ($ok);
72}
73
74
75### Start of Testing ###
76
77### Thread cancel ###
78
79# Set up to capture warning when thread terminates
80my @errs :shared;
81$SIG{__WARN__} = sub { push(@errs, @_); };
82
83
84sub thr_func {
85 # Thread 'cancellation' signal handler
86 $SIG{'KILL'} = sub {
87 ok(1, 'Thread received signal');
88 die("Thread killed\n");
89 };
90
91 # Thread sleeps until signalled
92 ok(1, 'Thread sleeping');
774c1dbe 93 {
94 local $SIG{'INT'} = sub {};
95 sleep(5);
96 }
c0003851 97 # Should not go past here
98 ok(0, 'Thread terminated normally');
99 return ('ERROR');
100}
101
102
103# Create thread
104my $thr = threads->create('thr_func');
105ok($thr && $thr->tid() == 1, 'Created thread');
106threads->yield();
107sleep(1);
108
109# Signal thread
110ok($thr->kill('KILL'), 'Signalled thread');
111threads->yield();
112
113# Interrupt thread's sleep call
114{
774c1dbe 115 # We can't be sure whether the signal itself will get delivered to this
116 # thread or the sleeping thread
c0003851 117 local $SIG{'INT'} = sub {};
118 ok(kill('INT', $$) || $^O eq 'MSWin32', q/Interrupt thread's sleep call/);
119}
120
121# Cleanup
122my $rc = $thr->join();
123ok(! $rc, 'No thread return value');
124
125# Check for thread termination message
126ok(@errs && $errs[0] =~ /Thread killed/, 'Thread termination warning');
127
128
129### Thread suspend/resume ###
130
131sub thr_func2
132{
133 my $sema = shift;
134 ok($sema, 'Thread received semaphore');
135
136 # Set up the signal handler for suspension/resumption
137 $SIG{'STOP'} = sub {
138 ok(1, 'Thread suspending');
139 $sema->down();
140 ok(1, 'Thread resuming');
141 $sema->up();
142 };
143
144 # Set up the signal handler for graceful termination
145 my $term = 0;
146 $SIG{'TERM'} = sub {
147 ok(1, 'Thread caught termination signal');
148 $term = 1;
149 };
150
151 # Do work until signalled to terminate
152 while (! $term) {
153 sleep(1);
154 }
155
156 ok(1, 'Thread done');
157 return ('OKAY');
158}
159
160
161# Create a semaphore for use in suspending the thread
162my $sema = Thread::Semaphore->new();
163ok($sema, 'Semaphore created');
164
165# Create a thread and send it the semaphore
166$thr = threads->create('thr_func2', $sema);
167ok($thr && $thr->tid() == 2, 'Created thread');
168threads->yield();
169sleep(1);
170
171# Suspend the thread
172$sema->down();
173ok($thr->kill('STOP'), 'Suspended thread');
174
175threads->yield();
176sleep(1);
177
178# Allow the thread to continue
179$sema->up();
180
181threads->yield();
182sleep(1);
183
184# Terminate the thread
185ok($thr->kill('TERM'), 'Signalled thread to terminate');
186
187$rc = $thr->join();
188ok($rc eq 'OKAY', 'Thread return value');
189
190# EOF