nthreads = 1;
cvcache = newHV();
curcop = &compiling;
- thr->flags = THRf_NORMAL;
+ thr->flags = THRf_R_JOINABLE;
+ MUTEX_INIT(&thr->mutex);
thr->next = thr;
thr->prev = thr;
#ifdef FAKE_THREADS
#ifdef USE_THREADS
#ifndef FAKE_THREADS
- /* Detach any remaining joinable threads apart from ourself */
+ /* Join with any remaining non-detached threads */
MUTEX_LOCK(&threads_mutex);
DEBUG_L(PerlIO_printf(PerlIO_stderr(),
- "perl_destruct: detaching remaining %d threads\n",
+ "perl_destruct: waiting for %d threads\n",
nthreads - 1));
for (t = thr->next; t != thr; t = t->next) {
- if (ThrSTATE(t) == THRf_NORMAL) {
- DETACH(t);
- ThrSETSTATE(t, THRf_DETACHED);
- DEBUG_L(PerlIO_printf(PerlIO_stderr(), "...detached %p\n", t));
+ MUTEX_LOCK(&t->mutex);
+ switch (ThrSTATE(t)) {
+ AV *av;
+ case R_ZOMBIE:
+ ThrSETSTATE(t, THRf_DEAD);
+ MUTEX_UNLOCK(&t->mutex);
+ nthreads--;
+ MUTEX_UNLOCK(&threads_mutex);
+ if (pthread_join(t->Tself, (void**)&av))
+ croak("panic: pthread_join failed during global destruction");
+ SvREFCNT_dec((SV*)av);
+ break;
+ case XXXX:
}
}
/* Now wait for the thread count nthreads to drop to one */
perl_thread Tself;
SV * Toursv;
- perl_mutex *Tthreadstart_mutexp;
HV * Tcvcache;
U32 flags;
+ perl_mutex mutex;
U32 tid;
struct thread *next, *prev; /* Circular linked list of threads */
typedef struct thread *Thread;
/* Values and macros for thr->flags */
-#define THRf_STATE_MASK 3
-#define THRf_NORMAL 0
-#define THRf_DETACHED 1
-#define THRf_JOINED 2
-#define THRf_DEAD 3
+#define THRf_STATE_MASK 7
+#define THRf_R_JOINABLE 0
+#define THRf_R_JOINED 1
+#define THRf_R_DETACHED 2
+#define THRf_ZOMBIE 3
+#define THRf_DEAD 4
-#define THRf_DIE_FATAL 4
+#define THRf_DIE_FATAL 8
-#define ThrSTATE(t) (t->flags & THRf_STATE_MASK)
+#define ThrSTATE(t) ((t)->flags)
#define ThrSETSTATE(t, s) STMT_START { \
- (t)->flags &= ~THRf_STATE_MASK; \
+ MUTEX_LOCK(&(t)->mutex); \
+ (t)->flags &= ~THRf_STATE_MASK; \
(t)->flags |= (s); \
- DEBUG_L(fprintf(stderr, "thread 0x%lx set to state %d\n", \
- (unsigned long)(t), (s))); \
+ MUTEX_UNLOCK(&(t)->mutex); \
+ DEBUG_L(PerlIO_printf(PerlIO_stderr(), \
+ "thread %p set to state %d\n", (t), (s))); \
} STMT_END
typedef struct condpair {
#define top_env (thr->Ttop_env)
#define runlevel (thr->Trunlevel)
-#define threadstart_mutexp (thr->Tthreadstart_mutexp)
#define cvcache (thr->Tcvcache)
#endif /* USE_THREADS */