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;
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. */
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++) {
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);
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;
--- /dev/null
+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);