use strict;
use warnings;
-use Config qw/%Config/;
+use lib 't/lib';
+use VPIT::TestHelpers;
+use Thread::Cleanup::TestThreads;
-BEGIN {
- if (!$Config{useithreads}) {
- require Test::More;
- Test::More->import;
- plan(skip_all => 'This perl wasn\'t built to support threads');
- }
-}
-
-use threads;
-use threads::shared;
-
-use Test::More tests => 5 * (2 + 2) + 1;
-
-BEGIN {
- defined and diag "Using threads $_" for $threads::VERSION;
- defined and diag "Using threads::shared $_" for $threads::shared::VERSION;
-}
+use Test::More 'no_plan';
use Thread::Cleanup;
my %called : shared;
+my $destr : shared;
my %nums : shared;
our $x = -1;
lock %nums;
$nums{$tid};
};
-
is $x, $num, "\$x in destructor of thread $tid";
+
+ my $gd = do {
+ lock $destr;
+ (defined $destr && $destr =~ /\[$tid\]/) ? 1 : undef;
+ };
+ is $gd, undef, "thread $tid destructor fires before global destruction";
+
local $x = $tid;
};
$ran{$tid}++;
}
+ my $immortal = VPIT::TestHelpers::Guard->new(sub {
+ # It seems we can't lock aggregates during global destruction, so we
+ # resort to using a string instead.
+ lock $destr;
+ $destr .= "[$tid]";
+ });
+ $immortal->{self} = $immortal;
+
{
lock %nums;
$nums{$tid} = $y;
local $x = -$tid;
}
-my @tids;
-my @t = map {
+my @threads = map {
local $x = $_;
- my $thr = threads->create(\&cb, $_);
- push @tids, $thr->tid;
- $thr;
+ spawn(\&cb, $_);
} 0 .. 4;
-$_->join for @t;
+my @tids = map $_->tid, @threads;
+
+$_->join for @threads;
is $x, -1, '$x in the main thread';