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