1#!perl 2 3BEGIN { 4 chdir 't' if -d 't'; 5 require './test.pl'; 6 set_up_inc( '../lib' ); 7 $| = 1; 8 9 skip_all_without_config('useithreads'); 10 skip_all_if_miniperl("no dynamic loading on miniperl, no threads"); 11 12 plan(30); 13} 14 15use strict; 16use warnings; 17use threads; 18 19# test that we don't get: 20# Attempt to free unreferenced scalar: SV 0x40173f3c 21fresh_perl_is(<<'EOI', 'ok', { }, 'delete() under threads'); 22use threads; 23threads->create(sub { my %h=(1,2); delete $h{1}})->join for 1..2; 24print "ok"; 25EOI 26 27#PR24660 28# test that we don't get: 29# Attempt to free unreferenced scalar: SV 0x814e0dc. 30fresh_perl_is(<<'EOI', 'ok', { }, 'weaken ref under threads'); 31use threads; 32no warnings 'experimental::builtin'; 33use builtin 'weaken'; 34my $data = "a"; 35my $obj = \$data; 36my $copy = $obj; 37weaken($copy); 38threads->create(sub { 1 })->join for (1..1); 39print "ok"; 40EOI 41 42#PR24663 43# test that we don't get: 44# panic: magic_killbackrefs. 45# Scalars leaked: 3 46fresh_perl_is(<<'EOI', 'ok', { }, 'weaken ref #2 under threads'); 47package Foo; 48sub new { bless {},shift } 49package main; 50use threads; 51no warnings 'experimental::builtin'; 52use builtin 'weaken'; 53my $object = Foo->new; 54my $ref = $object; 55weaken $ref; 56threads->create(sub { $ref = $object } )->join; # $ref = $object causes problems 57print "ok"; 58EOI 59 60#PR30333 - sort() crash with threads 61sub mycmp { length($b) <=> length($a) } 62 63sub do_sort_one_thread { 64 my $kid = shift; 65 print "# kid $kid before sort\n"; 66 my @list = ( 'x', 'yy', 'zzz', 'a', 'bb', 'ccc', 'aaaaa', 'z', 67 'hello', 's', 'thisisalongname', '1', '2', '3', 68 'abc', 'xyz', '1234567890', 'm', 'n', 'p' ); 69 70 for my $j (1..99999) { 71 for my $k (sort mycmp @list) {} 72 } 73 print "# kid $kid after sort, sleeping 1\n"; 74 sleep(1); 75 print "# kid $kid exit\n"; 76} 77 78sub do_sort_threads { 79 my $nthreads = shift; 80 my @kids = (); 81 for my $i (1..$nthreads) { 82 my $t = threads->create(\&do_sort_one_thread, $i); 83 print "# parent $$: continue\n"; 84 push(@kids, $t); 85 } 86 for my $t (@kids) { 87 print "# parent $$: waiting for join\n"; 88 $t->join(); 89 print "# parent $$: thread exited\n"; 90 } 91} 92 93do_sort_threads(2); # crashes 94ok(1); 95 96# Change 24643 made the mistake of assuming that CvCONST can only be true on 97# XSUBs. Somehow it can also end up on perl subs. 98fresh_perl_is(<<'EOI', 'ok', { }, 'cloning constant subs'); 99use constant x=>1; 100use threads; 101$SIG{__WARN__} = sub{}; 102async sub {}; 103print "ok"; 104EOI 105 106# From a test case by Tim Bunce in 107# http://www.nntp.perl.org/group/perl.perl5.porters/63123 108fresh_perl_is(<<'EOI', 'ok', { }, 'Ensure PL_linestr can be cloned'); 109use threads; 110print do 'op/threads_create.pl' || die $@; 111EOI 112 113 114# Scalars leaked: 1 115foreach my $BLOCK (qw(CHECK INIT)) { 116 fresh_perl_is(<<EOI, 'ok', { }, "threads in $BLOCK block"); 117 use threads; 118 $BLOCK { threads->create(sub {})->join; } 119 print 'ok'; 120EOI 121} 122 123# Scalars leaked: 1 124fresh_perl_is(<<'EOI', 'ok', { }, 'Bug #41138'); 125 use threads; 126 leak($x); 127 sub leak 128 { 129 local $x; 130 threads->create(sub {})->join(); 131 } 132 print 'ok'; 133EOI 134 135 136# [perl #45053] Memory corruption with heavy module loading in threads 137# 138# run-time usage of newCONSTSUB (as done by the IO boot code) wasn't 139# thread-safe - got occasional coredumps or malloc corruption 140watchdog(180, "process"); 141{ 142 local $SIG{__WARN__} = sub {}; # Ignore any thread creation failure warnings 143 my @t; 144 for (1..10) { 145 my $thr = threads->create( sub { require IO }); 146 last if !defined($thr); # Probably ran out of memory 147 push(@t, $thr); 148 } 149 $_->join for @t; 150 ok(1, '[perl #45053]'); 151} 152 153sub matchit { 154 is (ref $_[1], "Regexp"); 155 like ($_[0], $_[1]); 156} 157 158threads->new(\&matchit, "Pie", qr/pie/i)->join(); 159 160# tests in threads don't get counted, so 161curr_test(curr_test() + 2); 162 163 164# the seen_evals field of a regexp was getting zeroed on clone, so 165# within a thread it didn't know that a regex object contained a 'safe' 166# code expression, so it later died with 'Eval-group not allowed' when 167# you tried to interpolate the object 168 169sub safe_re { 170 my $re = qr/(?{1})/; # this is literal, so safe 171 eval { "a" =~ /$re$re/ }; # interpolating safe values, so safe 172 ok($@ eq "", 'clone seen-evals'); 173} 174threads->new(\&safe_re)->join(); 175 176# tests in threads don't get counted, so 177curr_test(curr_test() + 1); 178 179# This used to crash in 5.10.0 [perl #64954] 180 181undef *a; 182threads->new(sub {})->join; 183pass("undefing a typeglob doesn't cause a crash during cloning"); 184 185 186# Test we don't get: 187# panic: del_backref during global destruction. 188# when returning a non-closure sub from a thread and subsequently starting 189# a new thread. 190fresh_perl_is(<<'EOI', 'ok', { }, 'No del_backref panic [perl #70748]'); 191use threads; 192sub foo { return (sub { }); } 193my $bar = threads->create(\&foo)->join(); 194threads->create(sub { })->join(); 195print "ok"; 196EOI 197 198# Another, more reliable test for the same del_backref bug: 199fresh_perl_is( 200 <<' EOJ', 'ok', {}, 'No del_backref panic [perl #70748] (2)' 201 use threads; 202 push @bar, threads->create(sub{sub{}})->join() for 1...10; 203 print "ok"; 204 EOJ 205); 206 207# Simple closure-returning test: At least this case works (though it 208# leaks), and we don't want to break it. 209fresh_perl_is(<<'EOJ', 'foo', {}, 'returning a closure'); 210use threads; 211print create threads sub { 212 my $x = 'foo'; 213 sub{sub{$x}} 214}=>->join->()() 215 //"undef" 216EOJ 217 218# At the point of thread creation, $h{1} is on the temps stack. 219# The weak reference $a, however, is visible from the symbol table. 220fresh_perl_is(<<'EOI', 'ok', { }, 'Test for 34394ecd06e704e9'); 221 use threads; 222 no warnings 'experimental::builtin'; 223 use builtin 'weaken'; 224 %h = (1, 2); 225 $a = \$h{1}; 226 weaken($a); 227 delete $h{1} && threads->create(sub {}, shift)->join(); 228 print 'ok'; 229EOI 230 231# This will fail in "interesting" ways if stashes in clone_params is not 232# initialised correctly. 233fresh_perl_like(<<'EOI', qr/\AThread 1 terminated abnormally: Not a CODE reference/, { }, 'RT #73046'); 234 use strict; 235 use threads; 236 237 sub foo::bar; 238 239 my %h = (1, *{$::{'foo::'}}{HASH}); 240 *{$::{'foo::'}} = {}; 241 242 threads->create({}, delete $h{1})->join(); 243 244 print "end"; 245EOI 246 247fresh_perl_is(<<'EOI', 'ok', { }, '0 refcnt neither on tmps stack nor in @_'); 248 use threads; 249 no warnings 'experimental::builtin'; 250 use builtin 'weaken'; 251 my %h = (1, []); 252 my $a = $h{1}; 253 weaken($a); 254 delete $h{1} && threads->create(sub {}, shift)->join(); 255 print 'ok'; 256EOI 257 258{ 259 my $got; 260 sub stuff { 261 my $a; 262 if (@_) { 263 $a = "Leakage"; 264 threads->create(\&stuff)->join(); 265 } else { 266 is ($a, undef, 'RT #73086 - clone used to clone active pads'); 267 } 268 } 269 270 stuff(1); 271 272 curr_test(curr_test() + 1); 273} 274 275{ 276 my $got; 277 sub more_stuff { 278 my $a; 279 $::b = \$a; 280 if (@_) { 281 $a = "More leakage"; 282 threads->create(\&more_stuff)->join(); 283 } else { 284 is ($a, undef, 'Just special casing lexicals in ?{ ... }'); 285 } 286 } 287 288 more_stuff(1); 289 290 curr_test(curr_test() + 1); 291} 292 293# Test from Jerry Hedden, reduced by him from Object::InsideOut's tests. 294fresh_perl_is(<<'EOI', 'ok', { }, '0 refcnt during CLONE'); 295use strict; 296use warnings; 297 298use threads; 299 300{ 301 package My::Obj; 302 no warnings 'experimental::builtin'; 303 use builtin 'weaken'; 304 305 my %reg; 306 307 sub new 308 { 309 # Create object with ID = 1 310 my $class = shift; 311 my $id = 1; 312 my $obj = bless(\do{ my $scalar = $id; }, $class); 313 314 # Save weak copy of object for reference during cloning 315 weaken($reg{$id} = $obj); 316 317 # Return object 318 return $obj; 319 } 320 321 # Return the internal ID of the object 322 sub id 323 { 324 my $obj = shift; 325 return $$obj; 326 } 327 328 # During cloning 'look' at the object 329 sub CLONE { 330 foreach my $id (keys(%reg)) { 331 # This triggers SvREFCNT_inc() then SvREFCNT_dec() on the referent. 332 my $obj = $reg{$id}; 333 } 334 } 335} 336 337# Create object in 'main' thread 338my $obj = My::Obj->new(); 339my $id = $obj->id(); 340die "\$id is '$id'" unless $id == 1; 341 342# Access object in thread 343threads->create( 344 sub { 345 print $obj->id() == 1 ? "ok\n" : "not ok '" . $obj->id() . "'\n"; 346 } 347)->join(); 348 349EOI 350 351# make sure peephole optimiser doesn't recurse heavily. 352# (We run this inside a thread to get a small stack) 353 354{ 355 # lots of constructs that have o->op_other etc 356 my $code = <<'EOF'; 357 $r = $x || $y; 358 $x ||= $y; 359 $r = $x // $y; 360 $x //= $y; 361 $r = $x && $y; 362 $x &&= $y; 363 $r = $x ? $y : $z; 364 @a = map $x+1, @a; 365 @a = grep $x+1, @a; 366 $r = /$x/../$y/; 367 368 # this one will fail since we removed tail recursion optimisation 369 # with f11ca51e41e8 370 #while (1) { $x = 0 }; 371 372 while (0) { $x = 0 }; 373 for ($x=0; $y; $z=0) { $r = 0 }; 374 for (1) { $x = 0 }; 375 { $x = 0 }; 376 $x =~ s/a/$x + 1/e; 377EOF 378 $code = 'my ($r, $x,$y,$z,@a); return 5; ' . ($code x 1000); 379 my $res = threads->create(sub { eval $code})->join; 380 is($res, 5, "avoid peephole recursion"); 381} 382 383 384# [perl #78494] Pipes shared between threads block when closed 385{ 386 my $perl = which_perl; 387 $perl = qq'"$perl"' if $perl =~ /\s/; 388 open(my $OUT, "|$perl") || die("ERROR: $!"); 389 threads->create(sub { })->join; 390 ok(1, "Pipes shared between threads do not block when closed"); 391} 392 393# [perl #105208] Typeglob clones should not be cloned again during a join 394{ 395 threads->create(sub { sub { $::hypogamma = 3 } })->join->(); 396 is $::hypogamma, 3, 'globs cloned and joined are not recloned'; 397} 398 399fresh_perl_is( 400 'use threads;' . 401 'async { delete $::{INC}; eval q"my $foo : bar" } ->join; print "ok\n";', 402 "ok", 403 {}, 404 'no crash when deleting $::{INC} in thread' 405); 406 407fresh_perl_is(<<'CODE', 'ok', {}, 'no crash modifying extended array element'); 408use threads; 409my @a = 1; 410threads->create(sub { $#a = 1; $a[1] = 2; print qq/ok\n/ })->join; 411CODE 412 413fresh_perl_is(<<'CODE', '3.5,3.5', {}, 'RT #36664: Strange behavior of shared array'); 414use threads; 415use threads::shared; 416 417our @List : shared = (1..5); 418my $v = 3.5; 419$v > 0; 420$List[3] = $v; 421printf "%s,%s", @List[(3)], $List[3]; 422CODE 423 424fresh_perl_like(<<'CODE', qr/ok/, {}, 'RT #41121 binmode(STDOUT,":encoding(utf8) does not crash'); 425use threads; 426binmode(STDOUT,":encoding(utf8)"); 427threads->create(sub{}); 428print "ok\n"; 429CODE 430 431# EOF 432