1 #define PERL_NO_GET_CONTEXT
2 #include "EXTERN.h"
3 #include "perl.h"
4 #include "XSUB.h"
5 
6 /* Magic signature for Thread's mg_private is "Th" */
7 #define Thread_MAGIC_SIGNATURE 0x5468
8 
9 #ifdef __cplusplus
10 #ifdef I_UNISTD
11 #include <unistd.h>
12 #endif
13 #endif
14 #include <fcntl.h>
15 
16 static int sig_pipe[2];
17 
18 #ifndef THREAD_RET_TYPE
19 #define THREAD_RET_TYPE void *
20 #define THREAD_RET_CAST(x) ((THREAD_RET_TYPE) x)
21 #endif
22 
23 static void
remove_thread(pTHX_ Thread t)24 remove_thread(pTHX_ Thread t)
25 {
26 #ifdef USE_5005THREADS
27     DEBUG_S(WITH_THR(PerlIO_printf(Perl_debug_log,
28 				   "%p: remove_thread %p\n", thr, t)));
29     MUTEX_LOCK(&PL_threads_mutex);
30     MUTEX_DESTROY(&t->mutex);
31     PL_nthreads--;
32     t->prev->next = t->next;
33     t->next->prev = t->prev;
34     SvREFCNT_dec(t->oursv);
35     COND_BROADCAST(&PL_nthreads_cond);
36     MUTEX_UNLOCK(&PL_threads_mutex);
37 #endif
38 }
39 
40 static THREAD_RET_TYPE
threadstart(void * arg)41 threadstart(void *arg)
42 {
43 #ifdef USE_5005THREADS
44 #ifdef FAKE_THREADS
45     Thread savethread = thr;
46     LOGOP myop;
47     dSP;
48     I32 oldscope = PL_scopestack_ix;
49     I32 retval;
50     AV *av;
51     int i;
52 
53     DEBUG_S(PerlIO_printf(Perl_debug_log, "new thread %p starting at %s\n",
54 			  thr, SvPEEK(TOPs)));
55     thr = (Thread) arg;
56     savemark = TOPMARK;
57     thr->prev = thr->prev_run = savethread;
58     thr->next = savethread->next;
59     thr->next_run = savethread->next_run;
60     savethread->next = savethread->next_run = thr;
61     thr->wait_queue = 0;
62     thr->private = 0;
63 
64     /* Now duplicate most of perl_call_sv but with a few twists */
65     PL_op = (OP*)&myop;
66     Zero(PL_op, 1, LOGOP);
67     myop.op_flags = OPf_STACKED;
68     myop.op_next = Nullop;
69     myop.op_flags |= OPf_KNOW;
70     myop.op_flags |= OPf_WANT_LIST;
71     PL_op = pp_entersub(ARGS);
72     DEBUG_S(if (!PL_op)
73 	    PerlIO_printf(Perl_debug_log, "thread starts at Nullop\n"));
74     /*
75      * When this thread is next scheduled, we start in the right
76      * place. When the thread runs off the end of the sub, perl.c
77      * handles things, using savemark to figure out how much of the
78      * stack is the return value for any join.
79      */
80     thr = savethread;		/* back to the old thread */
81     return 0;
82 #else
83     Thread thr = (Thread) arg;
84     dSP;
85     I32 oldmark = TOPMARK;
86     I32 retval;
87     SV *sv;
88     AV *av;
89     int i;
90 
91 #if defined(MULTIPLICITY)
92     PERL_SET_INTERP(thr->interp);
93 #endif
94 
95     DEBUG_S(PerlIO_printf(Perl_debug_log, "new thread %p waiting to start\n",
96 			  thr));
97 
98     /*
99      * Wait until our creator releases us. If we didn't do this, then
100      * it would be potentially possible for out thread to carry on and
101      * do stuff before our creator fills in our "self" field. For example,
102      * if we went and created another thread which tried to JOIN with us,
103      * then we'd be in a mess.
104      */
105     MUTEX_LOCK(&thr->mutex);
106     MUTEX_UNLOCK(&thr->mutex);
107 
108     /*
109      * It's safe to wait until now to set the thread-specific pointer
110      * from our pthread_t structure to our struct perl_thread, since
111      * we're the only thread who can get at it anyway.
112      */
113     PERL_SET_THX(thr);
114 
115     DEBUG_S(PerlIO_printf(Perl_debug_log, "new thread %p starting at %s\n",
116 			  thr, SvPEEK(TOPs)));
117 
118     av = newAV();
119     sv = POPs;
120     PUTBACK;
121     ENTER;
122     SAVETMPS;
123     perl_call_sv(sv, G_ARRAY|G_EVAL);
124     SPAGAIN;
125     retval = SP - (PL_stack_base + oldmark);
126     SP = PL_stack_base + oldmark + 1;
127     if (SvCUR(thr->errsv)) {
128 	MUTEX_LOCK(&thr->mutex);
129 	thr->flags |= THRf_DID_DIE;
130 	MUTEX_UNLOCK(&thr->mutex);
131 	av_store(av, 0, &PL_sv_no);
132 	av_store(av, 1, newSVsv(thr->errsv));
133 	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p died: %s\n",
134 			      thr, SvPV(thr->errsv, PL_na)));
135     }
136     else {
137 	DEBUG_S(STMT_START {
138 	    for (i = 1; i <= retval; i++) {
139 		PerlIO_printf(Perl_debug_log, "%p return[%d] = %s\n",
140 				thr, i, SvPEEK(SP[i - 1]));
141 	    }
142 	} STMT_END);
143 	av_store(av, 0, &PL_sv_yes);
144 	for (i = 1; i <= retval; i++, SP++)
145 	    sv_setsv(*av_fetch(av, i, TRUE), SvREFCNT_inc(*SP));
146     }
147     FREETMPS;
148     LEAVE;
149 
150 #if 0
151     /* removed for debug */
152     SvREFCNT_dec(PL_curstack);
153 #endif
154     SvREFCNT_dec(thr->cvcache);
155     SvREFCNT_dec(thr->threadsv);
156     SvREFCNT_dec(thr->specific);
157     SvREFCNT_dec(thr->errsv);
158 
159     /*Safefree(cxstack);*/
160     while (PL_curstackinfo->si_next)
161 	PL_curstackinfo = PL_curstackinfo->si_next;
162     while (PL_curstackinfo) {
163 	PERL_SI *p = PL_curstackinfo->si_prev;
164 	SvREFCNT_dec(PL_curstackinfo->si_stack);
165 	Safefree(PL_curstackinfo->si_cxstack);
166 	Safefree(PL_curstackinfo);
167 	PL_curstackinfo = p;
168     }
169     Safefree(PL_markstack);
170     Safefree(PL_scopestack);
171     Safefree(PL_savestack);
172     Safefree(PL_retstack);
173     Safefree(PL_tmps_stack);
174     SvREFCNT_dec(PL_ofs_sv);
175 
176     SvREFCNT_dec(PL_rs);
177     SvREFCNT_dec(PL_statname);
178     SvREFCNT_dec(PL_errors);
179     Safefree(PL_screamfirst);
180     Safefree(PL_screamnext);
181     Safefree(PL_reg_start_tmp);
182     SvREFCNT_dec(PL_lastscream);
183     SvREFCNT_dec(PL_defoutgv);
184     Safefree(PL_reg_poscache);
185 
186     MUTEX_LOCK(&thr->mutex);
187     thr->thr_done = 1;
188     DEBUG_S(PerlIO_printf(Perl_debug_log,
189 			  "%p: threadstart finishing: state is %u\n",
190 			  thr, ThrSTATE(thr)));
191     switch (ThrSTATE(thr)) {
192     case THRf_R_JOINABLE:
193 	ThrSETSTATE(thr, THRf_ZOMBIE);
194 	MUTEX_UNLOCK(&thr->mutex);
195 	DEBUG_S(PerlIO_printf(Perl_debug_log,
196 			      "%p: R_JOINABLE thread finished\n", thr));
197 	break;
198     case THRf_R_JOINED:
199 	ThrSETSTATE(thr, THRf_DEAD);
200 	MUTEX_UNLOCK(&thr->mutex);
201 	remove_thread(aTHX_ thr);
202 	DEBUG_S(PerlIO_printf(Perl_debug_log,
203 			      "%p: R_JOINED thread finished\n", thr));
204 	break;
205     case THRf_R_DETACHED:
206 	ThrSETSTATE(thr, THRf_DEAD);
207 	MUTEX_UNLOCK(&thr->mutex);
208 	SvREFCNT_dec(av);
209 	DEBUG_S(PerlIO_printf(Perl_debug_log,
210 			      "%p: DETACHED thread finished\n", thr));
211 	remove_thread(aTHX_ thr);	/* This might trigger main thread to finish */
212 	break;
213     default:
214 	MUTEX_UNLOCK(&thr->mutex);
215 	croak("panic: illegal state %u at end of threadstart", ThrSTATE(thr));
216 	/* NOTREACHED */
217     }
218     return THREAD_RET_CAST(av);	/* Available for anyone to join with */
219 					/* us unless we're detached, in which */
220 					/* case noone sees the value anyway. */
221 #endif
222 #else
223     return THREAD_RET_CAST(NULL);
224 #endif
225 }
226 
227 static SV *
newthread(pTHX_ SV * startsv,AV * initargs,char * classname)228 newthread (pTHX_ SV *startsv, AV *initargs, char *classname)
229 {
230 #ifdef USE_5005THREADS
231     dSP;
232     Thread savethread;
233     int i;
234     SV *sv;
235     int err;
236 #ifndef THREAD_CREATE
237     static pthread_attr_t attr;
238     static int attr_inited = 0;
239     sigset_t fullmask, oldmask;
240     static int attr_joinable = PTHREAD_CREATE_JOINABLE;
241 #endif
242 
243     if (ckWARN(WARN_DEPRECATED))
244         Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
245 		    "5.005 threads are deprecated");
246     savethread = thr;
247     thr = new_struct_thread(thr);
248     /* temporarily pretend to be the child thread in case the
249      * XPUSHs() below want to grow the child's stack.  This is
250      * safe, since the other thread is not yet created, and we
251      * are the only ones who know about it */
252     PERL_SET_THX(thr);
253     SPAGAIN;
254     DEBUG_S(PerlIO_printf(Perl_debug_log,
255 			  "%p: newthread (%p), tid is %u, preparing stack\n",
256 			  savethread, thr, thr->tid));
257     /* The following pushes the arg list and startsv onto the *new* stack */
258     PUSHMARK(SP);
259     /* Could easily speed up the following greatly */
260     for (i = 0; i <= AvFILL(initargs); i++)
261 	XPUSHs(SvREFCNT_inc(*av_fetch(initargs, i, FALSE)));
262     XPUSHs(SvREFCNT_inc(startsv));
263     PUTBACK;
264 
265     /* On your marks... */
266     PERL_SET_THX(savethread);
267     MUTEX_LOCK(&thr->mutex);
268 
269 #ifdef THREAD_CREATE
270     err = THREAD_CREATE(thr, threadstart);
271 #else
272     /* Get set...  */
273     sigfillset(&fullmask);
274     if (sigprocmask(SIG_SETMASK, &fullmask, &oldmask) == -1)
275 	croak("panic: sigprocmask");
276     err = 0;
277     if (!attr_inited) {
278 	attr_inited = 1;
279 	err = pthread_attr_init(&attr);
280 #  ifdef THREAD_CREATE_NEEDS_STACK
281        if (err == 0)
282             err = pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK);
283        if (err)
284            croak("panic: pthread_attr_setstacksize failed");
285 #  endif
286 #  ifdef PTHREAD_ATTR_SETDETACHSTATE
287 	if (err == 0)
288 	    err = PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
289        if (err)
290            croak("panic: pthread_attr_setdetachstate failed");
291 #  else
292 	croak("panic: can't pthread_attr_setdetachstate");
293 #  endif
294     }
295     if (err == 0)
296 	err = PTHREAD_CREATE(&thr->self, attr, threadstart, (void*) thr);
297 #endif
298 
299     if (err) {
300 	MUTEX_UNLOCK(&thr->mutex);
301         DEBUG_S(PerlIO_printf(Perl_debug_log,
302 			      "%p: create of %p failed %d\n",
303 			      savethread, thr, err));
304 	/* Thread creation failed--clean up */
305 	SvREFCNT_dec(thr->cvcache);
306 	remove_thread(aTHX_ thr);
307 	for (i = 0; i <= AvFILL(initargs); i++)
308 	    SvREFCNT_dec(*av_fetch(initargs, i, FALSE));
309 	SvREFCNT_dec(startsv);
310 	return NULL;
311     }
312 
313 #ifdef THREAD_POST_CREATE
314     THREAD_POST_CREATE(thr);
315 #else
316     if (sigprocmask(SIG_SETMASK, &oldmask, 0))
317 	croak("panic: sigprocmask");
318 #endif
319 
320     sv = newSViv(thr->tid);
321     sv_magic(sv, thr->oursv, '~', 0, 0);
322     SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
323     sv = sv_bless(newRV_noinc(sv), gv_stashpv(classname, TRUE));
324 
325     /* Go */
326     MUTEX_UNLOCK(&thr->mutex);
327 
328     return sv;
329 #else
330 #  ifdef USE_ITHREADS
331     croak("This perl was built for \"ithreads\", which currently does not support Thread.pm.\n"
332 	  "Run \"perldoc Thread\" for more information");
333 #  else
334     croak("This perl was not built with support for 5.005-style threads.\n"
335 	  "Run \"perldoc Thread\" for more information");
336 #  endif
337     return &PL_sv_undef;
338 #endif
339 }
340 
341 static Signal_t handle_thread_signal (int sig);
342 
343 static Signal_t
handle_thread_signal(int sig)344 handle_thread_signal(int sig)
345 {
346     unsigned char c = (unsigned char) sig;
347     dTHX;
348     /*
349      * We're not really allowed to call fprintf in a signal handler
350      * so don't be surprised if this isn't robust while debugging
351      * with -DL.
352      */
353     DEBUG_S(PerlIO_printf(Perl_debug_log,
354 	    "handle_thread_signal: got signal %d\n", sig));
355     write(sig_pipe[1], &c, 1);
356 }
357 
358 MODULE = Thread		PACKAGE = Thread
359 PROTOTYPES: DISABLE
360 
361 void
362 new(classname, startsv, ...)
363 	char *		classname
364 	SV *		startsv
365 	AV *		av = av_make(items - 2, &ST(2));
366     PPCODE:
367 	XPUSHs(sv_2mortal(newthread(aTHX_ startsv, av, classname)));
368 
369 void
370 join(t)
371 	Thread	t
372     PREINIT:
373 #ifdef USE_5005THREADS
374 	AV *	av;
375 	int	i;
376 #endif
377     PPCODE:
378 #ifdef USE_5005THREADS
379 	if (t == thr)
380 	    croak("Attempt to join self");
381 	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: joining %p (state %u)\n",
382 			      thr, t, ThrSTATE(t)));
383     	MUTEX_LOCK(&t->mutex);
384 	switch (ThrSTATE(t)) {
385 	case THRf_R_JOINABLE:
386 	case THRf_R_JOINED:
387 	    ThrSETSTATE(t, THRf_R_JOINED);
388 	    MUTEX_UNLOCK(&t->mutex);
389 	    break;
390 	case THRf_ZOMBIE:
391 	    ThrSETSTATE(t, THRf_DEAD);
392 	    MUTEX_UNLOCK(&t->mutex);
393 	    remove_thread(aTHX_ t);
394 	    break;
395 	default:
396 	    MUTEX_UNLOCK(&t->mutex);
397 	    croak("can't join with thread");
398 	    /* NOTREACHED */
399 	}
400 	JOIN(t, &av);
401 
402 	sv_2mortal((SV*)av);
403 
404 	if (SvTRUE(*av_fetch(av, 0, FALSE))) {
405 	    /* Could easily speed up the following if necessary */
406 	    for (i = 1; i <= AvFILL(av); i++)
407 		XPUSHs(*av_fetch(av, i, FALSE));
408 	}
409 	else {
410 	    STRLEN n_a;
411 	    char *mess = SvPV(*av_fetch(av, 1, FALSE), n_a);
412 	    DEBUG_S(PerlIO_printf(Perl_debug_log,
413 				  "%p: join propagating die message: %s\n",
414 				  thr, mess));
415 	    croak(mess);
416 	}
417 #endif
418 
419 void
420 detach(t)
421 	Thread	t
422     CODE:
423 #ifdef USE_5005THREADS
424 	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: detaching %p (state %u)\n",
425 			      thr, t, ThrSTATE(t)));
426     	MUTEX_LOCK(&t->mutex);
427 	switch (ThrSTATE(t)) {
428 	case THRf_R_JOINABLE:
429 	    ThrSETSTATE(t, THRf_R_DETACHED);
430 	    /* fall through */
431 	case THRf_R_DETACHED:
432 	    DETACH(t);
433 	    MUTEX_UNLOCK(&t->mutex);
434 	    break;
435 	case THRf_ZOMBIE:
436 	    ThrSETSTATE(t, THRf_DEAD);
437 	    DETACH(t);
438 	    MUTEX_UNLOCK(&t->mutex);
439 	    remove_thread(aTHX_ t);
440 	    break;
441 	default:
442 	    MUTEX_UNLOCK(&t->mutex);
443 	    croak("can't detach thread");
444 	    /* NOTREACHED */
445 	}
446 #endif
447 
448 void
449 equal(t1, t2)
450 	Thread	t1
451 	Thread	t2
452     PPCODE:
453 	PUSHs((t1 == t2) ? &PL_sv_yes : &PL_sv_no);
454 
455 void
456 flags(t)
457 	Thread	t
458     PPCODE:
459 #ifdef USE_5005THREADS
460 	PUSHs(sv_2mortal(newSViv(t->flags)));
461 #endif
462 
463 void
464 done(t)
465 	Thread	t
466     PPCODE:
467 #ifdef USE_5005THREADS
468 	PUSHs(t->thr_done ? &PL_sv_yes : &PL_sv_no);
469 #endif
470 
471 void
472 self(classname)
473 	char *	classname
474     PREINIT:
475 #ifdef USE_5005THREADS
476 	SV *sv;
477 #endif
478     PPCODE:
479 #ifdef USE_5005THREADS
480 	sv = newSViv(thr->tid);
481 	sv_magic(sv, thr->oursv, '~', 0, 0);
482 	SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
483 	PUSHs(sv_2mortal(sv_bless(newRV_noinc(sv),
484 				  gv_stashpv(classname, TRUE))));
485 #endif
486 
487 U32
488 tid(t)
489 	Thread	t
490     CODE:
491 #ifdef USE_5005THREADS
492     	MUTEX_LOCK(&t->mutex);
493 	RETVAL = t->tid;
494     	MUTEX_UNLOCK(&t->mutex);
495 #else
496 	RETVAL = 0;
497 #endif
498     OUTPUT:
499 	RETVAL
500 
501 void
502 DESTROY(t)
503 	SV *	t
504     PPCODE:
505 	PUSHs(t ? &PL_sv_yes : &PL_sv_no);
506 
507 void
yield()508 yield()
509     CODE:
510 {
511 #ifdef USE_5005THREADS
512 	YIELD;
513 #endif
514 }
515 
516 void
517 cond_wait(sv)
518 	SV *	sv
519 PREINIT:
520 #ifdef USE_5005THREADS
521 	MAGIC *	mg;
522 #endif
523 CODE:
524 #ifdef USE_5005THREADS
525 	if (SvROK(sv))
526 	    sv = SvRV(sv);
527 
528 	mg = condpair_magic(sv);
529 	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: cond_wait %p\n", thr, sv));
530 	MUTEX_LOCK(MgMUTEXP(mg));
531 	if (MgOWNER(mg) != thr) {
532 	    MUTEX_UNLOCK(MgMUTEXP(mg));
533 	    croak("cond_wait for lock that we don't own\n");
534 	}
535 	MgOWNER(mg) = 0;
536 	COND_SIGNAL(MgOWNERCONDP(mg));
537 	COND_WAIT(MgCONDP(mg), MgMUTEXP(mg));
538 	while (MgOWNER(mg))
539 	    COND_WAIT(MgOWNERCONDP(mg), MgMUTEXP(mg));
540 	MgOWNER(mg) = thr;
541 	MUTEX_UNLOCK(MgMUTEXP(mg));
542 #endif
543 
544 void
545 cond_signal(sv)
546 	SV *	sv
547 PREINIT:
548 #ifdef USE_5005THREADS
549 	MAGIC *	mg;
550 #endif
551 CODE:
552 #ifdef USE_5005THREADS
553 	if (SvROK(sv))
554 	    sv = SvRV(sv);
555 
556 	mg = condpair_magic(sv);
557 	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: cond_signal %p\n",thr,sv));
558 	MUTEX_LOCK(MgMUTEXP(mg));
559 	if (MgOWNER(mg) != thr) {
560 	    MUTEX_UNLOCK(MgMUTEXP(mg));
561 	    croak("cond_signal for lock that we don't own\n");
562 	}
563 	COND_SIGNAL(MgCONDP(mg));
564 	MUTEX_UNLOCK(MgMUTEXP(mg));
565 #endif
566 
567 void
568 cond_broadcast(sv)
569 	SV *	sv
570 PREINIT:
571 #ifdef USE_5005THREADS
572 	MAGIC *	mg;
573 #endif
574 CODE:
575 #ifdef USE_5005THREADS
576 	if (SvROK(sv))
577 	    sv = SvRV(sv);
578 
579 	mg = condpair_magic(sv);
580 	DEBUG_S(PerlIO_printf(Perl_debug_log, "%p: cond_broadcast %p\n",
581 			      thr, sv));
582 	MUTEX_LOCK(MgMUTEXP(mg));
583 	if (MgOWNER(mg) != thr) {
584 	    MUTEX_UNLOCK(MgMUTEXP(mg));
585 	    croak("cond_broadcast for lock that we don't own\n");
586 	}
587 	COND_BROADCAST(MgCONDP(mg));
588 	MUTEX_UNLOCK(MgMUTEXP(mg));
589 #endif
590 
591 void
592 list(classname)
593 	char *	classname
594     PREINIT:
595 #ifdef USE_5005THREADS
596 	Thread	t;
597 	AV *	av;
598 	SV **	svp;
599 	int	n = 0;
600 #endif
601     PPCODE:
602 #ifdef USE_5005THREADS
603 	av = newAV();
604 	/*
605 	 * Iterate until we have enough dynamic storage for all threads.
606 	 * We mustn't do any allocation while holding threads_mutex though.
607 	 */
608 	MUTEX_LOCK(&PL_threads_mutex);
609 	do {
610 	    n = PL_nthreads;
611 	    MUTEX_UNLOCK(&PL_threads_mutex);
612 	    if (AvFILL(av) < n - 1) {
613 		int i = AvFILL(av);
614 		for (i = AvFILL(av); i < n - 1; i++) {
615 		    SV *sv = newSViv(0);	/* fill in tid later */
616 		    sv_magic(sv, 0, '~', 0, 0);	/* fill in other magic later */
617 		    av_push(av, sv_bless(newRV_noinc(sv),
618 					 gv_stashpv(classname, TRUE)));
619 
620 		}
621 	    }
622 	    MUTEX_LOCK(&PL_threads_mutex);
623 	} while (n < PL_nthreads);
624 	n = PL_nthreads;	/* Get the final correct value */
625 
626 	/*
627 	 * At this point, there's enough room to fill in av.
628 	 * Note that we are holding threads_mutex so the list
629 	 * won't change out from under us but all the remaining
630 	 * processing is "fast" (no blocking, malloc etc.)
631 	 */
632 	t = thr;
633 	svp = AvARRAY(av);
634 	do {
635 	    SV *sv = (SV*)SvRV(*svp);
636 	    sv_setiv(sv, t->tid);
637 	    SvMAGIC(sv)->mg_obj = SvREFCNT_inc(t->oursv);
638 	    SvMAGIC(sv)->mg_flags |= MGf_REFCOUNTED;
639 	    SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
640 	    t = t->next;
641 	    svp++;
642 	} while (t != thr);
643 	/*  */
644 	MUTEX_UNLOCK(&PL_threads_mutex);
645 	/* Truncate any unneeded slots in av */
646 	av_fill(av, n - 1);
647 	/* Finally, push all the new objects onto the stack and drop av */
648 	EXTEND(SP, n);
649 	for (svp = AvARRAY(av); n > 0; n--, svp++)
650 	    PUSHs(*svp);
651 	(void)sv_2mortal((SV*)av);
652 #endif
653 
654 
655 MODULE = Thread		PACKAGE = Thread::Signal
656 
657 void
658 kill_sighandler_thread()
659     PPCODE:
660 	write(sig_pipe[1], "\0", 1);
661 	PUSHs(&PL_sv_yes);
662 
663 void
664 init_thread_signals()
665     PPCODE:
666 	PL_sighandlerp = handle_thread_signal;
667 	if (pipe(sig_pipe) == -1)
668 	    XSRETURN_UNDEF;
669 	PUSHs(&PL_sv_yes);
670 
671 void
672 await_signal()
673     PREINIT:
674 	unsigned char c;
675 	SSize_t ret;
676     CODE:
677 	do {
678 	    ret = read(sig_pipe[0], &c, 1);
679 	} while (ret == -1 && errno == EINTR);
680 	if (ret == -1)
681 	    croak("panic: await_signal");
682 	ST(0) = sv_newmortal();
683 	if (ret)
684 	    sv_setsv(ST(0), c ? PL_psig_ptr[c] : &PL_sv_no);
685 	DEBUG_S(PerlIO_printf(Perl_debug_log,
686 			      "await_signal returning %s\n", SvPEEK(ST(0))));
687 
688 MODULE = Thread		PACKAGE = Thread::Specific
689 
690 void
691 data(classname = "Thread::Specific")
692 	char *	classname
693     PPCODE:
694 #ifdef USE_5005THREADS
695 	if (AvFILL(thr->specific) == -1) {
696 	    GV *gv = gv_fetchpv("Thread::Specific::FIELDS", TRUE, SVt_PVHV);
697 	    av_store(thr->specific, 0, newRV((SV*)GvHV(gv)));
698 	}
699 	XPUSHs(sv_bless(newRV((SV*)thr->specific),gv_stashpv(classname,TRUE)));
700 #endif
701