summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Beattie <mbeattie@sable.ox.ac.uk>1997-10-16 16:26:53 +0000
committerMalcolm Beattie <mbeattie@sable.ox.ac.uk>1997-10-16 16:26:53 +0000
commit0a00ffdb1e70eb883974513d0ee6f4afd54aca19 (patch)
treebc925e87ad5d1b9bd3d2839ae444604bc955b787
parent96c8aaf4c4918f137d2204ef25c74dac47dbae2f (diff)
downloadperl-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.xs8
-rw-r--r--Thread/Semaphore.pm8
-rw-r--r--list.t30
3 files changed, 38 insertions, 8 deletions
diff --git a/Thread.xs b/Thread.xs
index a5382d93a7..3dc25162a7 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 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);