From: Hugo van der Sanden Date: Thu, 26 Oct 2000 01:55:17 +0000 (+0100) Subject: Re: [PATCH 5.6.0]Add non-blocking thread doneness checking X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e01a9ca0f61dfca0a0ff0830bdab1ddd71342eec;p=p5sagit%2Fp5-mst-13.2.git Re: [PATCH 5.6.0]Add non-blocking thread doneness checking Message-Id: <200010260055.BAA27869@crypt.compulink.co.uk> minus one unneeded mutex lock/unlock pointed out by Dan Sugalski. p4raw-id: //depot/perl@7449 --- diff --git a/ext/Thread/Thread.pm b/ext/Thread/Thread.pm index 22ae4ef..f8a8a26 100644 --- a/ext/Thread/Thread.pm +++ b/ext/Thread/Thread.pm @@ -34,7 +34,6 @@ Thread - manipulate threads in Perl (EXPERIMENTAL, subject to change) my $tid = Thread->self->tid; my $tlist = Thread->list; - lock($scalar); yield(); @@ -191,7 +190,7 @@ assigned starting with one. The C method returns the flags for the thread. This is the integer value corresponding to the internal flags for the thread, and -the value man not be all that meaningful to you. +the value may not be all that meaningful to you. =item done diff --git a/ext/Thread/Thread.xs b/ext/Thread/Thread.xs index 27e2533..c911279 100644 --- a/ext/Thread/Thread.xs +++ b/ext/Thread/Thread.xs @@ -189,9 +189,9 @@ threadstart(void *arg) SvREFCNT_dec(PL_lastscream); SvREFCNT_dec(PL_defoutgv); Safefree(PL_reg_poscache); - thr->thr_done = 1; MUTEX_LOCK(&thr->mutex); + thr->thr_done = 1; DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: threadstart finishing: state is %u\n", thr, ThrSTATE(thr))); @@ -453,7 +453,7 @@ done(t) Thread t PPCODE: #ifdef USE_THREADS - PUSHs(t->thr_done ? &PL_sv_yes : &PL_sv_no); + PUSHs(t->thr_done ? &PL_sv_yes : &PL_sv_no); #endif void diff --git a/t/lib/thr5005.t b/t/lib/thr5005.t index 680e1af..bc6aed7 100755 --- a/t/lib/thr5005.t +++ b/t/lib/thr5005.t @@ -13,7 +13,7 @@ BEGIN { $ENV{PERL_DESTRUCT_LEVEL} = 0 unless $ENV{PERL_DESTRUCT_LEVEL} > 3; } $| = 1; -print "1..22\n"; +print "1..74\n"; use Thread 'yield'; print "ok 1\n"; @@ -129,3 +129,79 @@ $thr1->join; $thr2->join; $thr3->join; print "ok 22\n"; + +{ + my $THRf_STATE_MASK = 7; + my $THRf_R_JOINABLE = 0; + my $THRf_R_JOINED = 1; + my $THRf_R_DETACHED = 2; + my $THRf_ZOMBIE = 3; + my $THRf_DEAD = 4; + my $THRf_DID_DIE = 8; + sub _test { + my($test, $t, $state, $die) = @_; + my $flags = $t->flags; + if (($flags & $THRf_STATE_MASK) == $state + && !($flags & $THRf_DID_DIE) == !$die) { + print "ok $test\n"; + } else { + print <new(sub { sleep 4; die "thread die\n" }), + Thread->new(sub { die "thread die\n" }), + Thread->new(sub { sleep 4; 1 }), + Thread->new(sub { 1 }), + ) for 1, 2; + $_->detach for @t[grep $_ & 4, 0..$#t]; + + sleep 1; + my $test = 23; + for (0..7) { + my $t = $t[$_]; + my $flags = ($_ & 1) + ? ($_ & 4) ? $THRf_DEAD : $THRf_ZOMBIE + : ($_ & 4) ? $THRf_R_DETACHED : $THRf_R_JOINABLE; + _test($test++, $t, $flags, (($_ & 3) != 1) ? 0 : $THRf_DID_DIE); + printf "%sok %s\n", !$t->done == !($_ & 1) ? "" : "not ", $test++; + } +# $test = 39; + for (grep $_ & 1, 0..$#t) { + next if $_ & 4; # can't join detached threads + $t[$_]->eval; + my $die = ($_ & 2) ? "" : "thread die\n"; + printf "%sok %s\n", $@ eq $die ? "" : "not ", $test++; + } +# $test = 41; + for (0..7) { + my $t = $t[$_]; + my $flags = ($_ & 1) + ? ($_ & 4) ? $THRf_DEAD : $THRf_DEAD + : ($_ & 4) ? $THRf_R_DETACHED : $THRf_R_JOINABLE; + _test($test++, $t, $flags, (($_ & 3) != 1) ? 0 : $THRf_DID_DIE); + printf "%sok %s\n", !$t->done == !($_ & 1) ? "" : "not ", $test++; + } +# $test = 57; + for (grep !($_ & 1), 0..$#t) { + next if $_ & 4; # can't join detached threads + $t[$_]->eval; + my $die = ($_ & 2) ? "" : "thread die\n"; + printf "%sok %s\n", $@ eq $die ? "" : "not ", $test++; + } + sleep 1; # make sure even the detached threads are done sleeping +# $test = 59; + for (0..7) { + my $t = $t[$_]; + my $flags = ($_ & 1) + ? ($_ & 4) ? $THRf_DEAD : $THRf_DEAD + : ($_ & 4) ? $THRf_DEAD : $THRf_DEAD; + _test($test++, $t, $flags, ($_ & 2) ? 0 : $THRf_DID_DIE); + printf "%sok %s\n", $t->done ? "" : "not ", $test++; + } +# $test = 75; +}