Upgrade to threads 1.72
[p5sagit/p5-mst-13.2.git] / ext / threads / t / join.t
CommitLineData
0f1612a7 1use strict;
2use warnings;
3
e1c44605 4BEGIN {
0f1612a7 5 if ($ENV{'PERL_CORE'}){
6 chdir 't';
7 unshift @INC, '../lib';
8 }
9 use Config;
fc04eb16 10 if (! $Config{'useithreads'}) {
561ee912 11 print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
fc04eb16 12 exit(0);
e1c44605 13 }
14}
15
16use ExtUtils::testlib;
0f1612a7 17
e1c44605 18use threads;
e1c44605 19
fc04eb16 20BEGIN {
e301958b 21 if (! eval 'use threads::shared; 1') {
561ee912 22 print("1..0 # SKIP threads::shared not available\n");
58a3a76c 23 exit(0);
24 }
25
fc04eb16 26 $| = 1;
8718f9a1 27 print("1..20\n"); ### Number of tests that will be run ###
fc04eb16 28};
29
4dcb9e53 30my $TEST;
31BEGIN {
32 share($TEST);
33 $TEST = 1;
34}
fc04eb16 35
36ok(1, 'Loaded');
e1c44605 37
38sub ok {
39 my ($ok, $name) = @_;
40
fc04eb16 41 lock($TEST);
42 my $id = $TEST++;
d94cde48 43
e1c44605 44 # You have to do it this way or VMS will get confused.
fc04eb16 45 if ($ok) {
46 print("ok $id - $name\n");
47 } else {
48 print("not ok $id - $name\n");
49 printf("# Failed test at line %d\n", (caller)[2]);
50 }
e1c44605 51
fc04eb16 52 return ($ok);
e1c44605 53}
54
d90a703e 55sub skip {
561ee912 56 ok(1, '# SKIP ' . $_[0]);
d90a703e 57}
58
e1c44605 59
fc04eb16 60### Start of Testing ###
e1c44605 61
62{
63 my $retval = threads->create(sub { return ("hi") })->join();
64 ok($retval eq 'hi', "Check basic returnvalue");
65}
66{
67 my ($thread) = threads->create(sub { return (1,2,3) });
68 my @retval = $thread->join();
a31a65c0 69 ok($retval[0] == 1 && $retval[1] == 2 && $retval[2] == 3,'');
e1c44605 70}
71{
72 my $retval = threads->create(sub { return [1] })->join();
a31a65c0 73 ok($retval->[0] == 1,"Check that a array ref works",);
e1c44605 74}
75{
76 my $retval = threads->create(sub { return { foo => "bar" }})->join();
77 ok($retval->{foo} eq 'bar',"Check that hash refs work");
78}
79{
80 my $retval = threads->create( sub {
fc04eb16 81 open(my $fh, "+>threadtest") || die $!;
82 print $fh "test\n";
83 return $fh;
e1c44605 84 })->join();
85 ok(ref($retval) eq 'GLOB', "Check that we can return FH $retval");
86 print $retval "test2\n";
e1c44605 87 close($retval);
88 unlink("threadtest");
89}
90{
91 my $test = "hi";
92 my $retval = threads->create(sub { return $_[0]}, \$test)->join();
a31a65c0 93 ok($$retval eq 'hi','');
e1c44605 94}
95{
96 my $test = "hi";
97 share($test);
98 my $retval = threads->create(sub { return $_[0]}, \$test)->join();
a31a65c0 99 ok($$retval eq 'hi','');
e1c44605 100 $test = "foo";
a31a65c0 101 ok($$retval eq 'foo','');
e1c44605 102}
103{
104 my %foo;
105 share(%foo);
106 threads->create(sub {
fc04eb16 107 my $foo;
108 share($foo);
109 $foo = "thread1";
110 return $foo{bar} = \$foo;
e1c44605 111 })->join();
112 ok(1,"");
113}
e2975953 114
3cb9023d 115# We parse ps output so this is OS-dependent.
1e6e959c 116if ($^O eq 'linux') {
fc04eb16 117 # First modify $0 in a subthread.
118 #print "# mainthread: \$0 = $0\n";
119 threads->create(sub{ #print "# subthread: \$0 = $0\n";
120 $0 = "foobar";
121 #print "# subthread: \$0 = $0\n"
122 })->join;
123 #print "# mainthread: \$0 = $0\n";
124 #print "# pid = $$\n";
125 if (open PS, "ps -f |") { # Note: must work in (all) systems.
126 my ($sawpid, $sawexe);
127 while (<PS>) {
128 chomp;
129 #print "# [$_]\n";
130 if (/^\s*\S+\s+$$\s/) {
131 $sawpid++;
132 if (/\sfoobar\s*$/) { # Linux 2.2 leaves extra trailing spaces.
133 $sawexe++;
134 }
135 last;
136 }
137 }
138 close PS or die;
139 if ($sawpid) {
140 ok($sawpid && $sawexe, 'altering $0 is effective');
141 } else {
142 skip("\$0 check: did not see pid $$ in 'ps -f |'");
00c4b2c0 143 }
00c4b2c0 144 } else {
fc04eb16 145 skip("\$0 check: opening 'ps -f |' failed: $!");
00c4b2c0 146 }
e2975953 147} else {
fc04eb16 148 skip("\$0 check: only on Linux");
e2975953 149}
57b48062 150
151{
f4cc38af 152 my $t = threads->create(sub {});
f2cba68d 153 $t->join();
154 threads->create(sub {})->join();
155 eval { $t->join(); };
156 ok(($@ =~ /Thread already joined/), "Double join works");
157 eval { $t->detach(); };
158 ok(($@ =~ /Cannot detach a joined thread/), "Detach joined thread");
159}
160
161{
162 my $t = threads->create(sub {});
163 $t->detach();
164 threads->create(sub {})->join();
165 eval { $t->detach(); };
166 ok(($@ =~ /Thread already detached/), "Double detach works");
167 eval { $t->join(); };
168 ok(($@ =~ /Cannot join a detached thread/), "Join detached thread");
57b48062 169}
014f91c3 170
171{
fc04eb16 172 # The "use IO::File" is not actually used for anything; its only purpose
173 # is incite a lot of calls to newCONSTSUB. See the p5p archives for
174 # the thread "maint@20974 or before broke mp2 ithreads test".
ec54d15e 175 use IO::File;
fc04eb16 176 # This coredumped between #20930 and #21000
f4cc38af 177 $_->join for map threads->create(sub{ok($_, "stress newCONSTSUB")}), 1..2;
014f91c3 178}
179
8718f9a1 180{
181 my $go : shared = 0;
182
183 my $t = threads->create( sub {
184 lock($go);
185 cond_wait($go) until $go;
186 });
187
188 my $joiner = threads->create(sub { $_[0]->join }, $t);
189
190 threads->yield();
191 sleep 1;
192 eval { $t->join; };
193 ok(($@ =~ /^Thread already joined at/)?1:0, "Join pending join");
194
195 { lock($go); $go = 1; cond_signal($go); }
196 $joiner->join;
197}
198
199{
200 my $go : shared = 0;
201 my $t = threads->create( sub {
202 eval { threads->self->join; };
203 ok(($@ =~ /^Cannot join self/), "Join self");
204 lock($go); $go = 1; cond_signal($go);
205 });
206
207 { lock ($go); cond_wait($go) until $go; }
208 $t->join;
209}
210
211{
212 my $go : shared = 0;
213 my $t = threads->create( sub {
214 lock($go); cond_wait($go) until $go;
215 });
216 my $joiner = threads->create(sub { $_[0]->join; }, $t);
217
218 threads->yield();
219 sleep 1;
220 eval { $t->detach };
221 ok(($@ =~ /^Cannot detach a joined thread at/)?1:0, "Detach pending join");
222
223 { lock($go); $go = 1; cond_signal($go); }
224 $joiner->join;
225}
226
561ee912 227exit(0);
228
fc04eb16 229# EOF