From: Malcolm Beattie Date: Thu, 16 Oct 1997 16:26:53 +0000 (+0000) Subject: Correct threads_mutex locking in main thread destruction. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0a00ffdb1e70eb883974513d0ee6f4afd54aca19;p=p5sagit%2Fp5-mst-13.2.git 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 --- diff --git a/Thread.xs b/Thread.xs index a5382d9..3dc2516 100644 --- a/Thread.xs +++ b/Thread.xs @@ -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 d34d6bd..9e5852f 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 0000000..f13f4b2 --- /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);