diff options
author | Malcolm Beattie <mbeattie@sable.ox.ac.uk> | 1997-10-16 16:26:53 +0000 |
---|---|---|
committer | Malcolm Beattie <mbeattie@sable.ox.ac.uk> | 1997-10-16 16:26:53 +0000 |
commit | 0a00ffdb1e70eb883974513d0ee6f4afd54aca19 (patch) | |
tree | bc925e87ad5d1b9bd3d2839ae444604bc955b787 | |
parent | 96c8aaf4c4918f137d2204ef25c74dac47dbae2f (diff) | |
download | perl-0a00ffdb1e70eb883974513d0ee6f4afd54aca19.tar.gz |
Correct threads_mutex locking in main thread destruction.
Add per-interp thrsv to hold SV struct thread for main thread.
Move Thread.xs MUTEX_DESTROY from end of threadstart to remove_thread.
Add Thread/list.t test of Thread->list method.
Let Thread::Semaphore methods up and down take an extra argument.
p4raw-id: //depot/perlext/Thread@140
-rw-r--r-- | Thread.xs | 8 | ||||
-rw-r--r-- | Thread/Semaphore.pm | 8 | ||||
-rw-r--r-- | list.t | 30 |
3 files changed, 38 insertions, 8 deletions
@@ -15,6 +15,7 @@ Thread t; DEBUG_L(WITH_THR(PerlIO_printf(PerlIO_stderr(), "%p: remove_thread %p\n", thr, t))); MUTEX_LOCK(&threads_mutex); + MUTEX_DESTROY(&t->mutex); nthreads--; t->prev->next = t->next; t->next->prev = t->prev; @@ -181,7 +182,6 @@ void *arg; croak("panic: illegal state %u at end of threadstart", ThrSTATE(thr)); /* NOTREACHED */ } - MUTEX_DESTROY(&thr->mutex); return (void *) returnav; /* Available for anyone to join with us */ /* unless we are detached in which case */ /* noone will see the value anyway. */ @@ -474,7 +474,6 @@ list(class) do { n = nthreads; MUTEX_UNLOCK(&threads_mutex); - DEBUG_L(PerlIO_printf(PerlIO_stderr(), "list: n = %d\n", n)); if (AvFILL(av) < n - 1) { int i = AvFILL(av); for (i = AvFILL(av); i < n - 1; i++) { @@ -498,14 +497,13 @@ list(class) t = thr; svp = AvARRAY(av); do { - SV *sv = SvRV(*svp++); - DEBUG_L(PerlIO_printf(PerlIO_stderr(), - "list: filling in thread %p\n", t)); + SV *sv = (SV*)SvRV(*svp); sv_setiv(sv, t->tid); SvMAGIC(sv)->mg_obj = SvREFCNT_inc(t->Toursv); SvMAGIC(sv)->mg_flags |= MGf_REFCOUNTED; SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE; t = t->next; + svp++; } while (t != thr); /* */ MUTEX_UNLOCK(&threads_mutex); diff --git a/Thread/Semaphore.pm b/Thread/Semaphore.pm index d34d6bde97..9e5852f15c 100644 --- a/Thread/Semaphore.pm +++ b/Thread/Semaphore.pm @@ -10,14 +10,16 @@ sub new { sub down { use attrs qw(locked method); my $s = shift; - cond_wait $s until $$s > 0; - $$s--; + my $inc = @_ ? shift : 1; + cond_wait $s until $$s >= $inc; + $$s -= $inc; } sub up { use attrs qw(locked method); my $s = shift; - $$s++ > 0 and cond_broadcast $s; + my $inc = @_ ? shift : 1; + ($$s += $inc) > 0 and cond_broadcast $s; } 1; diff --git a/list.t b/list.t new file mode 100644 index 0000000000..f13f4b266a --- /dev/null +++ b/list.t @@ -0,0 +1,30 @@ +use Thread qw(async); +use Thread::Semaphore; + +my $sem = Thread::Semaphore->new(0); + +$nthreads = 4; + +for (my $i = 0; $i < $nthreads; $i++) { + async { + my $tid = Thread->self->tid; + print "thread $tid started...\n"; + $sem->down; + print "thread $tid finishing\n"; + }; +} + +print "main: started $nthreads threads\n"; +sleep 2; + +my @list = Thread->list; +printf "main: Thread->list returned %d threads\n", scalar(@list); + +foreach my $t (@list) { + print "inspecting thread $t...\n"; + print "...deref is $$t\n"; + print "...flags = ", $t->flags, "\n"; + print "...tid = ", $t->tid, "\n"; +} +print "main thread telling workers to finish off...\n"; +$sem->up($nthreads); |