summaryrefslogtreecommitdiff
path: root/perl.c
diff options
context:
space:
mode:
authorMalcolm Beattie <mbeattie@sable.ox.ac.uk>1997-10-15 16:57:45 +0000
committerMalcolm Beattie <mbeattie@sable.ox.ac.uk>1997-10-15 16:57:45 +0000
commitc7848ba184fac8eca4125f4296d6e09fee2c1846 (patch)
treeb3622e9e800badf79382bfc95e96ea8cd2733b5a /perl.c
parentf826a10b5944692b2da706f4a0ac5056f28e8c6d (diff)
downloadperl-c7848ba184fac8eca4125f4296d6e09fee2c1846.tar.gz
Finish thread state machine: fixes global destruction of threads,
detaching, joining etc. Alter FAKE_THREADS-specific fields to use new HAVE_THREAD_INTERN stuff. Updates docs. Various fixes to Thread.xs. p4raw-id: //depot/perl@131
Diffstat (limited to 'perl.c')
-rw-r--r--perl.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/perl.c b/perl.c
index dea0cfdbd5..9f49b835ff 100644
--- a/perl.c
+++ b/perl.c
@@ -136,12 +136,9 @@ register PerlInterpreter *sv_interp;
MUTEX_INIT(&thr->mutex);
thr->next = thr;
thr->prev = thr;
-#ifdef FAKE_THREADS
- self = thr;
- thr->next_run = thr->prev_run = thr;
- thr->wait_queue = 0;
- thr->private = 0;
thr->tid = 0;
+#ifdef HAVE_THREAD_INTERN
+ init_thread_intern(thr);
#else
self = pthread_self();
if (pthread_key_create(&thr_key, 0))
@@ -244,13 +241,15 @@ register PerlInterpreter *sv_interp;
/* Join with any remaining non-detached threads */
MUTEX_LOCK(&threads_mutex);
DEBUG_L(PerlIO_printf(PerlIO_stderr(),
- "perl_destruct: waiting for %d threads\n",
+ "perl_destruct: waiting for %d threads...\n",
nthreads - 1));
for (t = thr->next; t != thr; t = t->next) {
MUTEX_LOCK(&t->mutex);
switch (ThrSTATE(t)) {
AV *av;
- case R_ZOMBIE:
+ case THRf_ZOMBIE:
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+ "perl_destruct: joining zombie %p\n", t));
ThrSETSTATE(t, THRf_DEAD);
MUTEX_UNLOCK(&t->mutex);
nthreads--;
@@ -258,15 +257,37 @@ register PerlInterpreter *sv_interp;
if (pthread_join(t->Tself, (void**)&av))
croak("panic: pthread_join failed during global destruction");
SvREFCNT_dec((SV*)av);
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+ "perl_destruct: joined zombie %p OK\n", t));
break;
- case XXXX:
+ case THRf_R_JOINABLE:
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+ "perl_destruct: detaching thread %p\n", t));
+ ThrSETSTATE(t, THRf_R_DETACHED);
+ /*
+ * We unlock threads_mutex and t->mutex in the opposite order
+ * from which we locked them just so that DETACH won't
+ * deadlock if it panics. It's only a breach of good style
+ * not a bug since they are unlocks not locks.
+ */
+ MUTEX_UNLOCK(&threads_mutex);
+ DETACH(t);
+ MUTEX_UNLOCK(&t->mutex);
+ break;
+ default:
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+ "perl_destruct: ignoring %p (state %u)\n",
+ t, ThrSTATE(t)));
+ MUTEX_UNLOCK(&t->mutex);
+ MUTEX_UNLOCK(&threads_mutex);
+ /* fall through and out */
}
}
/* Now wait for the thread count nthreads to drop to one */
while (nthreads > 1)
{
DEBUG_L(PerlIO_printf(PerlIO_stderr(),
- "perl_destruct: waiting for %d threads\n",
+ "perl_destruct: final wait for %d threads\n",
nthreads - 1));
COND_WAIT(&nthreads_cond, &threads_mutex);
}