From: Vincent Pit Date: Fri, 24 Dec 2010 16:31:57 +0000 (+0100) Subject: Fix and test thread safety X-Git-Tag: v0.01~27 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FTest-Leaner.git;a=commitdiff_plain;h=eb0bd56068ca67ea93f621ef38f59dec9bdbbcd8;hp=41367a04c268486fb815420a103f80e28ffefd63 Fix and test thread safety --- diff --git a/MANIFEST b/MANIFEST index cd8249f..c4a91c3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -14,5 +14,6 @@ t/15-use-skip_all.t t/16-done_testing.t t/17-plan-done_testing.t t/19-comments.t +t/80-threads.t t/20-ok.t t/21-is.t diff --git a/lib/Test/Leaner.pm b/lib/Test/Leaner.pm index f0f490e..c4c577d 100644 --- a/lib/Test/Leaner.pm +++ b/lib/Test/Leaner.pm @@ -25,22 +25,26 @@ BEGIN { } } -my ($plan, $test, $failed, $no_diag); +my $TAP_STREAM = *STDOUT; +my $DIAG_STREAM = *STDERR; + +my ($plan, $test, $failed, $no_diag, $done_testing); sub NO_PLAN () { -1 } sub SKIP_ALL () { -2 } BEGIN { - threads::shared::share($plan), lock $plan if THREADSAFE; + if (THREADSAFE) { + threads::shared::share($_) for $plan, $test, $failed, $no_diag; + } + + lock $plan if THREADSAFE; $plan = undef; $test = 0; $failed = 0; } -my $TAP_STREAM = *STDOUT; -my $DIAG_STREAM = *STDERR; - sub carp { my $level = 1 + ($Test::Builder::Level || 0); my ($file, $line) = (caller $level)[1, 2]; @@ -194,8 +198,6 @@ sub skip { last SKIP; } -my $done_testing; - sub done_testing { my ($count) = @_; diff --git a/t/80-threads.t b/t/80-threads.t new file mode 100644 index 0000000..3b0a595 --- /dev/null +++ b/t/80-threads.t @@ -0,0 +1,47 @@ +#!perl -T + +use strict; +use warnings; + +sub skipall { + my ($msg) = @_; + require Test::Leaner; + Test::Leaner::plan(skip_all => $msg); +} + +use Config qw/%Config/; + +BEGIN { + my $force = $ENV{PERL_TEST_LEANER_TEST_THREADS} ? 1 : !1; + my $t_v = $force ? '0' : '1.67'; + skipall 'This perl wasn\'t built to support threads' + unless $Config{useithreads}; + skipall 'perl 5.13.4 required to test thread safety' + unless $force or $] >= 5.013004; + skipall "threads $t_v required to test thread safety" + unless eval "use threads $t_v; 1"; +} + +use Test::Leaner; # after threads + +BEGIN { + skipall 'This Test::Leaner isn\'t thread safe' unless Test::Leaner::THREADSAFE; + plan tests => 8 * 10; + defined and diag "Using threads $_" for $threads::VERSION; +} + +sub tick { + sleep 1 if rand() < 0.5; +} + +sub worker { + my $tid = threads->tid; + diag "spawned thread $tid"; + tick; + for (1 .. 10) { + pass "test $_ in thread $tid"; + tick; + } +} + +$_->join for map threads->create(\&worker), 1 .. 8;