summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo van der Sanden <hv@crypt.org>2000-10-26 02:55:17 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2000-10-26 04:49:16 +0000
commite01a9ca0f61dfca0a0ff0830bdab1ddd71342eec (patch)
tree40dd0d05a450d410657dcaf7c691dd7437a138ad
parentdedcc4d4fc24baa272bfe8f4ae99d9497526bbb6 (diff)
downloadperl-e01a9ca0f61dfca0a0ff0830bdab1ddd71342eec.tar.gz
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
-rw-r--r--ext/Thread/Thread.pm3
-rw-r--r--ext/Thread/Thread.xs4
-rwxr-xr-xt/lib/thr5005.t78
3 files changed, 80 insertions, 5 deletions
diff --git a/ext/Thread/Thread.pm b/ext/Thread/Thread.pm
index 22ae4ef404..f8a8a26bbc 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<flags> 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 27e2533f3e..c911279c1d 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 680e1af3e7..bc6aed7182 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 <<BAD;
+not ok $test\t# got flags $flags not @{[ $state + ($die ? $THRf_DID_DIE : 0) ]}
+BAD
+ }
+ }
+
+ my @t;
+ push @t, (
+ Thread->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;
+}