Upgrade to Devel::PPPort 3.08_07
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.xs
1 #define PERL_NO_GET_CONTEXT
2 #include "EXTERN.h"
3 #include "perl.h"
4 #include "XSUB.h"
5 #ifdef HAS_PPPORT_H
6 #  define NEED_PL_signals
7 #  define NEED_newRV_noinc
8 #  define NEED_sv_2pv_nolen
9 #  include "ppport.h"
10 #  include "threads.h"
11 #endif
12
13 #ifdef USE_ITHREADS
14
15 #ifdef WIN32
16 #  include <windows.h>
17    /* Supposed to be in Winbase.h */
18 #  ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
19 #    define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
20 #  endif
21 #  include <win32thread.h>
22 #else
23 #  ifdef OS2
24 typedef perl_os_thread pthread_t;
25 #  else
26 #    include <pthread.h>
27 #  endif
28 #  include <thread.h>
29 #  define PERL_THREAD_SETSPECIFIC(k,v) pthread_setspecific(k,v)
30 #  ifdef OLD_PTHREADS_API
31 #    define PERL_THREAD_DETACH(t) pthread_detach(&(t))
32 #  else
33 #    define PERL_THREAD_DETACH(t) pthread_detach((t))
34 #  endif
35 #endif
36 #if !defined(HAS_GETPAGESIZE) && defined(I_SYS_PARAM)
37 #  include <sys/param.h>
38 #endif
39
40 /* Values for 'state' member */
41 #define PERL_ITHR_JOINABLE      0
42 #define PERL_ITHR_DETACHED      1
43 #define PERL_ITHR_JOINED        2
44 #define PERL_ITHR_FINISHED      4
45
46 typedef struct _ithread {
47     struct _ithread *next;      /* Next thread in the list */
48     struct _ithread *prev;      /* Prev thread in the list */
49     PerlInterpreter *interp;    /* The threads interpreter */
50     UV tid;                     /* Threads module's thread id */
51     perl_mutex mutex;           /* Mutex for updating things in this struct */
52     int count;                  /* How many SVs have a reference to us */
53     int state;                  /* Detached, joined, finished, etc. */
54     int gimme;                  /* Context of create */
55     SV *init_function;          /* Code to run */
56     SV *params;                 /* Args to pass function */
57 #ifdef WIN32
58     DWORD  thr;                 /* OS's idea if thread id */
59     HANDLE handle;              /* OS's waitable handle */
60 #else
61     pthread_t thr;              /* OS's handle for the thread */
62 #endif
63     IV stack_size;
64 } ithread;
65
66
67 /* Used by Perl interpreter for thread context switching */
68 #define MY_CXT_KEY "threads::_guts" XS_VERSION
69
70 typedef struct {
71     ithread *thread;
72 } my_cxt_t;
73
74 START_MY_CXT
75
76
77 /* Linked list of all threads */
78 static ithread *threads;
79
80 /* Protects the creation and destruction of threads*/
81 static perl_mutex create_destruct_mutex;
82
83 static UV tid_counter = 0;
84 static IV active_threads = 0;
85 static IV joinable_threads = 0;
86 #ifdef THREAD_CREATE_NEEDS_STACK
87 static IV default_stack_size = THREAD_CREATE_NEEDS_STACK;
88 #else
89 static IV default_stack_size = 0;
90 #endif
91 static IV page_size = 0;
92
93
94 /* Used by Perl interpreter for thread context switching */
95 static void
96 S_ithread_set(pTHX_ ithread *thread)
97 {
98     dMY_CXT;
99     MY_CXT.thread = thread;
100 }
101
102 static ithread *
103 S_ithread_get(pTHX)
104 {
105     dMY_CXT;
106     return (MY_CXT.thread);
107 }
108
109
110 /* Free any data (such as the Perl interpreter) attached to an ithread
111  * structure.  This is a bit like undef on SVs, where the SV isn't freed,
112  * but the PVX is.  Must be called with thread->mutex already held.
113  */
114 static void
115 S_ithread_clear(pTHX_ ithread *thread)
116 {
117     PerlInterpreter *interp;
118
119     assert(thread->state & PERL_ITHR_FINISHED &&
120            thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED));
121
122     interp = thread->interp;
123     if (interp) {
124         dTHXa(interp);
125
126         PERL_SET_CONTEXT(interp);
127         S_ithread_set(aTHX_ thread);
128
129         SvREFCNT_dec(thread->params);
130         thread->params = Nullsv;
131
132         perl_destruct(interp);
133         thread->interp = NULL;
134     }
135     if (interp)
136         perl_free(interp);
137
138     PERL_SET_CONTEXT(aTHX);
139 }
140
141
142 /* Free an ithread structure and any attached data if its count == 0 */
143 static void
144 S_ithread_destruct(pTHX_ ithread *thread)
145 {
146 #ifdef WIN32
147     HANDLE handle;
148 #endif
149
150     MUTEX_LOCK(&thread->mutex);
151
152     /* Thread is still in use */
153     if (thread->count != 0) {
154         MUTEX_UNLOCK(&thread->mutex);
155         return;
156     }
157
158     MUTEX_LOCK(&create_destruct_mutex);
159     /* Main thread (0) is immortal and should never get here */
160     assert(thread->tid != 0);
161
162     /* Remove from circular list of threads */
163     thread->next->prev = thread->prev;
164     thread->prev->next = thread->next;
165     thread->next = NULL;
166     thread->prev = NULL;
167     MUTEX_UNLOCK(&create_destruct_mutex);
168
169     /* Thread is now disowned */
170     S_ithread_clear(aTHX_ thread);
171
172 #ifdef WIN32
173     handle = thread->handle;
174     thread->handle = NULL;
175 #endif
176     MUTEX_UNLOCK(&thread->mutex);
177     MUTEX_DESTROY(&thread->mutex);
178
179 #ifdef WIN32
180     if (handle)
181         CloseHandle(handle);
182 #endif
183
184     /* Call PerlMemShared_free() in the context of the "first" interpreter
185      * per http://www.nntp.perl.org/group/perl.perl5.porters/110772
186      */
187     aTHX = PL_curinterp;
188     PerlMemShared_free(thread);
189 }
190
191
192 /* Called on exit */
193 int
194 Perl_ithread_hook(pTHX)
195 {
196     int veto_cleanup = 0;
197     MUTEX_LOCK(&create_destruct_mutex);
198     if ((aTHX == PL_curinterp) && (joinable_threads != 1)) {
199         if (ckWARN_d(WARN_THREADS)) {
200             Perl_warn(aTHX_ "A thread exited while %" IVdf " threads were running", joinable_threads);
201         }
202         veto_cleanup = 1;
203     }
204     MUTEX_UNLOCK(&create_destruct_mutex);
205     return (veto_cleanup);
206 }
207
208
209 /* MAGIC (in mg.h sense) hooks */
210
211 int
212 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
213 {
214     ithread *thread = (ithread *)mg->mg_ptr;
215     SvIV_set(sv, PTR2IV(thread));
216     SvIOK_on(sv);
217     return (0);
218 }
219
220 int
221 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
222 {
223     ithread *thread = (ithread *)mg->mg_ptr;
224     int cleanup;
225
226     MUTEX_LOCK(&thread->mutex);
227     cleanup = ((--thread->count == 0) &&
228                (thread->state & PERL_ITHR_FINISHED) &&
229                (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)));
230     MUTEX_UNLOCK(&thread->mutex);
231
232     if (cleanup)
233         S_ithread_destruct(aTHX_ thread);
234     return (0);
235 }
236
237 int
238 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
239 {
240     ithread *thread = (ithread *)mg->mg_ptr;
241     MUTEX_LOCK(&thread->mutex);
242     thread->count++;
243     MUTEX_UNLOCK(&thread->mutex);
244     return (0);
245 }
246
247 MGVTBL ithread_vtbl = {
248     ithread_mg_get,     /* get */
249     0,                  /* set */
250     0,                  /* len */
251     0,                  /* clear */
252     ithread_mg_free,    /* free */
253     0,                  /* copy */
254     ithread_mg_dup      /* dup */
255 };
256
257
258 /* Provided default, minimum and rational stack sizes */
259 static IV
260 good_stack_size(pTHX_ IV stack_size)
261 {
262     /* Use default stack size if no stack size specified */
263     if (! stack_size)
264         return (default_stack_size);
265
266 #ifdef PTHREAD_STACK_MIN
267     /* Can't use less than minimum */
268     if (stack_size < PTHREAD_STACK_MIN) {
269         if (ckWARN_d(WARN_THREADS)) {
270             Perl_warn(aTHX_ "Using minimum thread stack size of %" IVdf, (IV)PTHREAD_STACK_MIN);
271         }
272         return (PTHREAD_STACK_MIN);
273     }
274 #endif
275
276     /* Round up to page size boundary */
277     if (page_size <= 0) {
278 #if defined(HAS_SYSCONF) && (defined(_SC_PAGESIZE) || defined(_SC_MMAP_PAGE_SIZE))
279         SETERRNO(0, SS_NORMAL);
280 #  ifdef _SC_PAGESIZE
281         page_size = sysconf(_SC_PAGESIZE);
282 #  else
283         page_size = sysconf(_SC_MMAP_PAGE_SIZE);
284 #  endif
285         if ((long)page_size < 0) {
286             if (errno) {
287                 SV * const error = get_sv("@", FALSE);
288                 (void)SvUPGRADE(error, SVt_PV);
289                 Perl_croak(aTHX_ "PANIC: sysconf: %s", SvPV_nolen(error));
290             } else {
291                 Perl_croak(aTHX_ "PANIC: sysconf: pagesize unknown");
292             }
293         }
294 #else
295 #  ifdef HAS_GETPAGESIZE
296         page_size = getpagesize();
297 #  else
298 #    if defined(I_SYS_PARAM) && defined(PAGESIZE)
299         page_size = PAGESIZE;
300 #    else
301         page_size = 8192;   /* A conservative default */
302 #    endif
303 #  endif
304         if (page_size <= 0)
305             Perl_croak(aTHX_ "PANIC: bad pagesize %" IVdf, (IV)page_size);
306 #endif
307     }
308     stack_size = ((stack_size + (page_size - 1)) / page_size) * page_size;
309
310     return (stack_size);
311 }
312
313
314 /* Starts executing the thread.
315  * Passed as the C level function to run in the new thread.
316  */
317 #ifdef WIN32
318 static THREAD_RET_TYPE
319 S_ithread_run(LPVOID arg)
320 #else
321 static void *
322 S_ithread_run(void * arg)
323 #endif
324 {
325     ithread *thread = (ithread *)arg;
326     int cleanup;
327
328     dTHXa(thread->interp);
329     PERL_SET_CONTEXT(thread->interp);
330     S_ithread_set(aTHX_ thread);
331
332 #if 0
333     /* Far from clear messing with ->thr child-side is a good idea */
334     MUTEX_LOCK(&thread->mutex);
335 #ifdef WIN32
336     thread->thr = GetCurrentThreadId();
337 #else
338     thread->thr = pthread_self();
339 #endif
340     MUTEX_UNLOCK(&thread->mutex);
341 #endif
342
343     PL_perl_destruct_level = 2;
344
345     {
346         AV *params = (AV *)SvRV(thread->params);
347         int len = (int)av_len(params)+1;
348         int ii;
349
350         dSP;
351         ENTER;
352         SAVETMPS;
353
354         /* Put args on the stack */
355         PUSHMARK(SP);
356         for (ii=0; ii < len; ii++) {
357             XPUSHs(av_shift(params));
358         }
359         PUTBACK;
360
361         /* Run the specified function */
362         len = (int)call_sv(thread->init_function, thread->gimme|G_EVAL);
363
364         /* Remove args from stack and put back in params array */
365         SPAGAIN;
366         for (ii=len-1; ii >= 0; ii--) {
367             SV *sv = POPs;
368             av_store(params, ii, SvREFCNT_inc(sv));
369         }
370
371         /* Check for failure */
372         if (SvTRUE(ERRSV) && ckWARN_d(WARN_THREADS)) {
373             Perl_warn(aTHX_ "Thread %" UVuf " terminated abnormally: %" SVf, thread->tid, ERRSV);
374         }
375
376         FREETMPS;
377         LEAVE;
378
379         /* Release function ref */
380         SvREFCNT_dec(thread->init_function);
381         thread->init_function = Nullsv;
382     }
383
384     PerlIO_flush((PerlIO *)NULL);
385
386     MUTEX_LOCK(&thread->mutex);
387     /* Mark as finished */
388     thread->state |= PERL_ITHR_FINISHED;
389     /* Cleanup if detached */
390     cleanup = (thread->state & PERL_ITHR_DETACHED);
391     MUTEX_UNLOCK(&thread->mutex);
392
393     if (cleanup)
394         S_ithread_destruct(aTHX_ thread);
395
396     MUTEX_LOCK(&create_destruct_mutex);
397     active_threads--;
398     if (!cleanup) {
399         joinable_threads--;
400     }
401     MUTEX_UNLOCK(&create_destruct_mutex);
402
403 #ifdef WIN32
404     return ((DWORD)0);
405 #else
406     return (0);
407 #endif
408 }
409
410
411 /* Type conversion helper functions */
412 static SV *
413 ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
414 {
415     SV *sv;
416     MAGIC *mg;
417
418     if (inc) {
419         MUTEX_LOCK(&thread->mutex);
420         thread->count++;
421         MUTEX_UNLOCK(&thread->mutex);
422     }
423
424     if (! obj) {
425         obj = newSV(0);
426     }
427
428     sv = newSVrv(obj, classname);
429     sv_setiv(sv, PTR2IV(thread));
430     mg = sv_magicext(sv, Nullsv, PERL_MAGIC_shared_scalar, &ithread_vtbl, (char *)thread, 0);
431     mg->mg_flags |= MGf_DUP;
432     SvREADONLY_on(sv);
433
434     return (obj);
435 }
436
437 static ithread *
438 SV_to_ithread(pTHX_ SV *sv)
439 {
440     /* Argument is a thread */
441     if (SvROK(sv)) {
442       return (INT2PTR(ithread *, SvIV(SvRV(sv))));
443     }
444     /* Argument is classname, therefore return current thread */
445     return (S_ithread_get(aTHX));
446 }
447
448
449 /* threads->create()
450  * Called in context of parent thread.
451  */
452 static SV *
453 S_ithread_create(
454         pTHX_ SV *obj,
455         char     *classname,
456         SV       *init_function,
457         IV        stack_size,
458         int       gimme,
459         SV       *params)
460 {
461     ithread     *thread;
462     CLONE_PARAMS clone_param;
463     ithread     *current_thread = S_ithread_get(aTHX);
464
465     SV         **tmps_tmp = PL_tmps_stack;
466     IV           tmps_ix  = PL_tmps_ix;
467 #ifndef WIN32
468     int          rc_stack_size = 0;
469     int          rc_thread_create = 0;
470 #endif
471
472     MUTEX_LOCK(&create_destruct_mutex);
473
474     /* Allocate thread structure */
475     thread = (ithread *)PerlMemShared_malloc(sizeof(ithread));
476     if (!thread) {
477         MUTEX_UNLOCK(&create_destruct_mutex);
478         PerlLIO_write(PerlIO_fileno(Perl_error_log), PL_no_mem, strlen(PL_no_mem));
479         my_exit(1);
480     }
481     Zero(thread, 1, ithread);
482
483     /* Add to threads list */
484     thread->next = threads;
485     thread->prev = threads->prev;
486     threads->prev = thread;
487     thread->prev->next = thread;
488
489     /* Set count to 1 immediately in case thread exits before
490      * we return to caller!
491      */
492     thread->count = 1;
493
494     MUTEX_INIT(&thread->mutex);
495     thread->tid = tid_counter++;
496     thread->stack_size = good_stack_size(aTHX_ stack_size);
497     thread->gimme = gimme;
498
499     /* "Clone" our interpreter into the thread's interpreter.
500      * This gives thread access to "static data" and code.
501      */
502     PerlIO_flush((PerlIO *)NULL);
503     S_ithread_set(aTHX_ thread);
504
505     SAVEBOOL(PL_srand_called); /* Save this so it becomes the correct value */
506     PL_srand_called = FALSE;   /* Set it to false so we can detect if it gets
507                                   set during the clone */
508
509 #ifdef WIN32
510     thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
511 #else
512     thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
513 #endif
514
515     /* perl_clone() leaves us in new interpreter's context.  As it is tricky
516      * to spot an implicit aTHX, create a new scope with aTHX matching the
517      * context for the duration of our work for new interpreter.
518      */
519     {
520         dTHXa(thread->interp);
521
522         MY_CXT_CLONE;
523
524         /* Here we remove END blocks since they should only run in the thread
525          * they are created
526          */
527         SvREFCNT_dec(PL_endav);
528         PL_endav = newAV();
529
530         if (SvPOK(init_function)) {
531             thread->init_function = newSV(0);
532             sv_copypv(thread->init_function, init_function);
533         } else {
534             clone_param.flags = 0;
535             thread->init_function = sv_dup(init_function, &clone_param);
536             if (SvREFCNT(thread->init_function) == 0) {
537                 SvREFCNT_inc(thread->init_function);
538             }
539         }
540
541         thread->params = sv_dup(params, &clone_param);
542         SvREFCNT_inc(thread->params);
543
544         /* The code below checks that anything living on the tmps stack and
545          * has been cloned (so it lives in the ptr_table) has a refcount
546          * higher than 0.
547          *
548          * If the refcount is 0 it means that a something on the stack/context
549          * was holding a reference to it and since we init_stacks() in
550          * perl_clone that won't get cleaned and we will get a leaked scalar.
551          * The reason it was cloned was that it lived on the @_ stack.
552          *
553          * Example of this can be found in bugreport 15837 where calls in the
554          * parameter list end up as a temp.
555          *
556          * One could argue that this fix should be in perl_clone.
557          */
558         while (tmps_ix > 0) {
559             SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
560             tmps_ix--;
561             if (sv && SvREFCNT(sv) == 0) {
562                 SvREFCNT_inc(sv);
563                 SvREFCNT_dec(sv);
564             }
565         }
566
567         SvTEMP_off(thread->init_function);
568         ptr_table_free(PL_ptr_table);
569         PL_ptr_table = NULL;
570         PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
571     }
572     S_ithread_set(aTHX_ current_thread);
573     PERL_SET_CONTEXT(aTHX);
574
575     /* Create/start the thread */
576 #ifdef WIN32
577     thread->handle = CreateThread(NULL,
578                                   (DWORD)thread->stack_size,
579                                   S_ithread_run,
580                                   (LPVOID)thread,
581                                   STACK_SIZE_PARAM_IS_A_RESERVATION,
582                                   &thread->thr);
583 #else
584     {
585         static pthread_attr_t attr;
586         static int attr_inited = 0;
587         static int attr_joinable = PTHREAD_CREATE_JOINABLE;
588         if (! attr_inited) {
589             pthread_attr_init(&attr);
590             attr_inited = 1;
591         }
592
593 #  ifdef PTHREAD_ATTR_SETDETACHSTATE
594         /* Threads start out joinable */
595         PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
596 #  endif
597
598 #  ifdef _POSIX_THREAD_ATTR_STACKSIZE
599         /* Set thread's stack size */
600         if (thread->stack_size > 0) {
601             rc_stack_size = pthread_attr_setstacksize(&attr, (size_t)thread->stack_size);
602         }
603 #  endif
604
605         /* Create the thread */
606         if (! rc_stack_size) {
607 #  ifdef OLD_PTHREADS_API
608             rc_thread_create = pthread_create(&thread->thr,
609                                               attr,
610                                               S_ithread_run,
611                                               (void *)thread);
612 #  else
613 #    if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
614             pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
615 #    endif
616             rc_thread_create = pthread_create(&thread->thr,
617                                               &attr,
618                                               S_ithread_run,
619                                               (void *)thread);
620 #  endif
621         }
622
623 #  ifdef _POSIX_THREAD_ATTR_STACKSIZE
624         /* Try to get thread's actual stack size */
625         {
626             size_t stacksize;
627 #ifdef HPUX1020
628             stacksize = pthread_attr_getstacksize(attr);
629 #else
630             if (! pthread_attr_getstacksize(&attr, &stacksize))
631 #endif
632                 if (stacksize > 0) {
633                     thread->stack_size = (IV)stacksize;
634                 }
635         }
636 #  endif
637     }
638 #endif
639
640     /* Check for errors */
641 #ifdef WIN32
642     if (thread->handle == NULL) {
643 #else
644     if (rc_stack_size || rc_thread_create) {
645 #endif
646         MUTEX_UNLOCK(&create_destruct_mutex);
647         sv_2mortal(params);
648         S_ithread_destruct(aTHX_ thread);
649 #ifndef WIN32
650         if (ckWARN_d(WARN_THREADS)) {
651             if (rc_stack_size)
652                 Perl_warn(aTHX_ "Thread creation failed: pthread_attr_setstacksize(%" IVdf ") returned %d", thread->stack_size, rc_stack_size);
653             else
654                 Perl_warn(aTHX_ "Thread creation failed: pthread_create returned %d", rc_thread_create);
655         }
656 #endif
657         return (&PL_sv_undef);
658     }
659
660     active_threads++;
661     joinable_threads++;
662     MUTEX_UNLOCK(&create_destruct_mutex);
663
664     sv_2mortal(params);
665
666     return (ithread_to_SV(aTHX_ obj, thread, classname, FALSE));
667 }
668
669 #endif /* USE_ITHREADS */
670
671
672 MODULE = threads    PACKAGE = threads    PREFIX = ithread_
673 PROTOTYPES: DISABLE
674
675 #ifdef USE_ITHREADS
676
677 void
678 ithread_create(...)
679     PREINIT:
680         char *classname;
681         ithread *thread;
682         SV *function_to_call;
683         AV *params;
684         HV *specs;
685         IV stack_size;
686         int context;
687         char *str;
688         char ch;
689         int idx;
690         int ii;
691     CODE:
692         if ((items >= 2) && SvROK(ST(1)) && SvTYPE(SvRV(ST(1)))==SVt_PVHV) {
693             if (--items < 2)
694                 Perl_croak(aTHX_ "Usage: threads->create(\\%specs, function, ...)");
695             specs = (HV*)SvRV(ST(1));
696             idx = 1;
697         } else {
698             if (items < 2)
699                 Perl_croak(aTHX_ "Usage: threads->create(function, ...)");
700             specs = NULL;
701             idx = 0;
702         }
703
704         if (sv_isobject(ST(0))) {
705             /* $thr->create() */
706             classname = HvNAME(SvSTASH(SvRV(ST(0))));
707             thread = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
708             stack_size = thread->stack_size;
709         } else {
710             /* threads->create() */
711             classname = (char *)SvPV_nolen(ST(0));
712             stack_size = default_stack_size;
713         }
714
715         function_to_call = ST(idx+1);
716
717         context = -1;
718         if (specs) {
719             /* stack_size */
720             if (hv_exists(specs, "stack", 5)) {
721                 stack_size = SvIV(*hv_fetch(specs, "stack", 5, 0));
722             } else if (hv_exists(specs, "stacksize", 9)) {
723                 stack_size = SvIV(*hv_fetch(specs, "stacksize", 9, 0));
724             } else if (hv_exists(specs, "stack_size", 10)) {
725                 stack_size = SvIV(*hv_fetch(specs, "stack_size", 10, 0));
726             }
727
728             /* context */
729             if (hv_exists(specs, "context", 7)) {
730                 str = (char *)SvPV_nolen(*hv_fetch(specs, "context", 7, 0));
731                 switch (*str) {
732                     case 'a':
733                     case 'A':
734                         context = G_ARRAY;
735                         break;
736                     case 's':
737                     case 'S':
738                         context = G_SCALAR;
739                         break;
740                     case 'v':
741                     case 'V':
742                         context = G_VOID;
743                         break;
744                     default:
745                         Perl_croak(aTHX_ "Invalid context: %s", str);
746                 }
747             } else if (hv_exists(specs, "array", 5)) {
748                 if (SvTRUE(*hv_fetch(specs, "array", 5, 0))) {
749                     context = G_ARRAY;
750                 }
751             } else if (hv_exists(specs, "scalar", 6)) {
752                 if (SvTRUE(*hv_fetch(specs, "scalar", 6, 0))) {
753                     context = G_SCALAR;
754                 }
755             } else if (hv_exists(specs, "void", 4)) {
756                 if (SvTRUE(*hv_fetch(specs, "void", 4, 0))) {
757                     context = G_VOID;
758                 }
759             }
760         }
761         if (context == -1) {
762             context = GIMME_V;  /* Implicit context */
763         } else {
764             context |= (GIMME_V & (~(G_ARRAY|G_SCALAR|G_VOID)));
765         }
766
767         /* Function args */
768         params = newAV();
769         if (items > 2) {
770             for (ii=2; ii < items ; ii++) {
771                 av_push(params, SvREFCNT_inc(ST(idx+ii)));
772             }
773         }
774
775         /* Create thread */
776         ST(0) = sv_2mortal(S_ithread_create(aTHX_ Nullsv,
777                                             classname,
778                                             function_to_call,
779                                             stack_size,
780                                             context,
781                                             newRV_noinc((SV*)params)));
782         /* XSRETURN(1); - implied */
783
784
785 void
786 ithread_list(...)
787     PREINIT:
788         char *classname;
789         ithread *thread;
790         int list_context;
791         IV count = 0;
792     PPCODE:
793         /* Class method only */
794         if (SvROK(ST(0)))
795             Perl_croak(aTHX_ "Usage: threads->list()");
796         classname = (char *)SvPV_nolen(ST(0));
797
798         /* Calling context */
799         list_context = (GIMME_V == G_ARRAY);
800
801         /* Walk through threads list */
802         MUTEX_LOCK(&create_destruct_mutex);
803         for (thread = threads->next;
804              thread != threads;
805              thread = thread->next)
806         {
807             /* Ignore detached or joined threads */
808             if (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)) {
809                 continue;
810             }
811             /* Push object on stack if list context */
812             if (list_context) {
813                 XPUSHs(sv_2mortal(ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE)));
814             }
815             count++;
816         }
817         MUTEX_UNLOCK(&create_destruct_mutex);
818         /* If scalar context, send back count */
819         if (! list_context) {
820             XSRETURN_IV(count);
821         }
822
823
824 void
825 ithread_self(...)
826     PREINIT:
827         char *classname;
828         ithread *thread;
829     CODE:
830         /* Class method only */
831         if (SvROK(ST(0)))
832             Perl_croak(aTHX_ "Usage: threads->self()");
833         classname = (char *)SvPV_nolen(ST(0));
834
835         thread = S_ithread_get(aTHX);
836
837         ST(0) = sv_2mortal(ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE));
838         /* XSRETURN(1); - implied */
839
840
841 void
842 ithread_tid(...)
843     PREINIT:
844         ithread *thread;
845     CODE:
846         thread = SV_to_ithread(aTHX_ ST(0));
847         XST_mUV(0, thread->tid);
848         /* XSRETURN(1); - implied */
849
850
851 void
852 ithread_join(...)
853     PREINIT:
854         ithread *thread;
855         int join_err;
856         AV *params;
857         int len;
858         int ii;
859 #ifdef WIN32
860         DWORD waitcode;
861 #else
862         void *retval;
863 #endif
864     PPCODE:
865         /* Object method only */
866         if (! sv_isobject(ST(0)))
867             Perl_croak(aTHX_ "Usage: $thr->join()");
868
869         /* Check if the thread is joinable */
870         thread = SV_to_ithread(aTHX_ ST(0));
871         MUTEX_LOCK(&thread->mutex);
872         join_err = (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED));
873         MUTEX_UNLOCK(&thread->mutex);
874         if (join_err) {
875             if (join_err & PERL_ITHR_DETACHED) {
876                 Perl_croak(aTHX_ "Cannot join a detached thread");
877             } else {
878                 Perl_croak(aTHX_ "Thread already joined");
879             }
880         }
881
882         /* Join the thread */
883 #ifdef WIN32
884         waitcode = WaitForSingleObject(thread->handle, INFINITE);
885 #else
886         pthread_join(thread->thr, &retval);
887 #endif
888
889         MUTEX_LOCK(&thread->mutex);
890         /* Mark as joined */
891         thread->state |= PERL_ITHR_JOINED;
892
893         /* Get the return value from the call_sv */
894         {
895             AV *params_copy;
896             PerlInterpreter *other_perl;
897             CLONE_PARAMS clone_params;
898             ithread *current_thread;
899
900             params_copy = (AV *)SvRV(thread->params);
901             other_perl = thread->interp;
902             clone_params.stashes = newAV();
903             clone_params.flags = CLONEf_JOIN_IN;
904             PL_ptr_table = ptr_table_new();
905             current_thread = S_ithread_get(aTHX);
906             S_ithread_set(aTHX_ thread);
907             /* Ensure 'meaningful' addresses retain their meaning */
908             ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
909             ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
910             ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
911             params = (AV *)sv_dup((SV*)params_copy, &clone_params);
912             S_ithread_set(aTHX_ current_thread);
913             SvREFCNT_dec(clone_params.stashes);
914             SvREFCNT_inc(params);
915             ptr_table_free(PL_ptr_table);
916             PL_ptr_table = NULL;
917         }
918
919         /* We are finished with the thread */
920         S_ithread_clear(aTHX_ thread);
921         MUTEX_UNLOCK(&thread->mutex);
922
923         /* If no return values, then just return */
924         if (! params) {
925             XSRETURN_UNDEF;
926         }
927
928         /* Put return values on stack */
929         len = (int)AvFILL(params);
930         for (ii=0; ii <= len; ii++) {
931             SV* param = av_shift(params);
932             XPUSHs(sv_2mortal(param));
933         }
934
935         /* Free return value array */
936         SvREFCNT_dec(params);
937
938
939 void
940 ithread_yield(...)
941     CODE:
942         YIELD;
943
944
945 void
946 ithread_detach(...)
947     PREINIT:
948         ithread *thread;
949         int detach_err;
950         int cleanup;
951     CODE:
952         thread = SV_to_ithread(aTHX_ ST(0));
953         MUTEX_LOCK(&thread->mutex);
954
955         /* Check if the thread is detachable */
956         if ((detach_err = (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)))) {
957             MUTEX_UNLOCK(&thread->mutex);
958             if (detach_err & PERL_ITHR_DETACHED) {
959                 Perl_croak(aTHX_ "Thread already detached");
960             } else {
961                 Perl_croak(aTHX_ "Cannot detach a joined thread");
962             }
963         }
964
965         /* Detach the thread */
966         thread->state |= PERL_ITHR_DETACHED;
967 #ifdef WIN32
968         /* Windows has no 'detach thread' function */
969 #else
970         PERL_THREAD_DETACH(thread->thr);
971 #endif
972         /* Cleanup if finished */
973         cleanup = (thread->state & PERL_ITHR_FINISHED);
974         MUTEX_UNLOCK(&thread->mutex);
975
976         if (cleanup)
977             S_ithread_destruct(aTHX_ thread);
978         else {
979             MUTEX_LOCK(&create_destruct_mutex);
980             joinable_threads--;
981             MUTEX_UNLOCK(&create_destruct_mutex);
982         }
983
984
985 void
986 ithread_kill(...)
987     PREINIT:
988         ithread *thread;
989         char *sig_name;
990         IV signal;
991     CODE:
992         /* Must have safe signals */
993         if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
994             Perl_croak(aTHX_ "Cannot signal other threads without safe signals");
995
996         /* Object method only */
997         if (! sv_isobject(ST(0)))
998             Perl_croak(aTHX_ "Usage: $thr->kill('SIG...')");
999
1000         /* Get thread */
1001         thread = SV_to_ithread(aTHX_ ST(0));
1002
1003         /* Get signal */
1004         sig_name = SvPV_nolen(ST(1));
1005         if (isALPHA(*sig_name)) {
1006             if (*sig_name == 'S' && sig_name[1] == 'I' && sig_name[2] == 'G')
1007                 sig_name += 3;
1008             if ((signal = whichsig(sig_name)) < 0)
1009                 Perl_croak(aTHX_ "Unrecognized signal name: %s", sig_name);
1010         } else
1011             signal = SvIV(ST(1));
1012
1013         /* Set the signal for the thread */
1014         {
1015             dTHXa(thread->interp);
1016             PL_psig_pend[signal]++;
1017             PL_sig_pending = 1;
1018         }
1019
1020         /* Return the thread to allow for method chaining */
1021         ST(0) = ST(0);
1022         /* XSRETURN(1); - implied */
1023
1024
1025 void
1026 ithread_DESTROY(...)
1027     CODE:
1028         sv_unmagic(SvRV(ST(0)), PERL_MAGIC_shared_scalar);
1029
1030
1031 void
1032 ithread_equal(...)
1033     PREINIT:
1034         int are_equal = 0;
1035     CODE:
1036         /* Compares TIDs to determine thread equality */
1037         if (sv_isobject(ST(0)) && sv_isobject(ST(1))) {
1038             ithread *thr1 = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
1039             ithread *thr2 = INT2PTR(ithread *, SvIV(SvRV(ST(1))));
1040             are_equal = (thr1->tid == thr2->tid);
1041         }
1042         if (are_equal) {
1043             XST_mYES(0);
1044         } else {
1045             /* Return 0 on false for backward compatibility */
1046             XST_mIV(0, 0);
1047         }
1048         /* XSRETURN(1); - implied */
1049
1050
1051 void
1052 ithread_object(...)
1053     PREINIT:
1054         char *classname;
1055         UV tid;
1056         ithread *thread;
1057         int found = 0;
1058     CODE:
1059         /* Class method only */
1060         if (SvROK(ST(0)))
1061             Perl_croak(aTHX_ "Usage: threads->object($tid)");
1062         classname = (char *)SvPV_nolen(ST(0));
1063
1064         if ((items < 2) || ! SvOK(ST(1))) {
1065             XSRETURN_UNDEF;
1066         }
1067
1068         /* threads->object($tid) */
1069         tid = SvUV(ST(1));
1070
1071         /* Walk through threads list */
1072         MUTEX_LOCK(&create_destruct_mutex);
1073         for (thread = threads->next;
1074              thread != threads;
1075              thread = thread->next)
1076         {
1077             /* Look for TID, but ignore detached or joined threads */
1078             if ((thread->tid != tid) ||
1079                 (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)))
1080             {
1081                 continue;
1082             }
1083             /* Put object on stack */
1084             ST(0) = sv_2mortal(ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE));
1085             found = 1;
1086             break;
1087         }
1088         MUTEX_UNLOCK(&create_destruct_mutex);
1089         if (! found) {
1090             XSRETURN_UNDEF;
1091         }
1092         /* XSRETURN(1); - implied */
1093
1094
1095 void
1096 ithread__handle(...);
1097     PREINIT:
1098         ithread *thread;
1099     CODE:
1100         thread = SV_to_ithread(aTHX_ ST(0));
1101 #ifdef WIN32
1102         XST_mUV(0, PTR2UV(&thread->handle));
1103 #else
1104         XST_mUV(0, PTR2UV(&thread->thr));
1105 #endif
1106         /* XSRETURN(1); - implied */
1107
1108
1109 void
1110 ithread_get_stack_size(...)
1111     PREINIT:
1112         IV stack_size;
1113     CODE:
1114         if (sv_isobject(ST(0))) {
1115             /* $thr->get_stack_size() */
1116             ithread *thread = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
1117             stack_size = thread->stack_size;
1118         } else {
1119             /* threads->get_stack_size() */
1120             stack_size = default_stack_size;
1121         }
1122         XST_mIV(0, stack_size);
1123         /* XSRETURN(1); - implied */
1124
1125
1126 void
1127 ithread_set_stack_size(...)
1128     PREINIT:
1129         IV old_size;
1130     CODE:
1131         if (items != 2)
1132             Perl_croak(aTHX_ "Usage: threads->set_stack_size($size)");
1133         if (sv_isobject(ST(0)))
1134             Perl_croak(aTHX_ "Cannot change stack size of an existing thread");
1135
1136         old_size = default_stack_size;
1137         default_stack_size = good_stack_size(aTHX_ SvIV(ST(1)));
1138         XST_mIV(0, old_size);
1139         /* XSRETURN(1); - implied */
1140
1141 #endif /* USE_ITHREADS */
1142
1143
1144 BOOT:
1145 {
1146 #ifdef USE_ITHREADS
1147     /* The 'main' thread is thread 0.
1148      * It is detached (unjoinable) and immortal.
1149      */
1150
1151     ithread *thread;
1152     MY_CXT_INIT;
1153
1154     PL_perl_destruct_level = 2;
1155     MUTEX_INIT(&create_destruct_mutex);
1156     MUTEX_LOCK(&create_destruct_mutex);
1157
1158     PL_threadhook = &Perl_ithread_hook;
1159
1160     thread = (ithread *)PerlMemShared_malloc(sizeof(ithread));
1161     if (! thread) {
1162         PerlLIO_write(PerlIO_fileno(Perl_error_log), PL_no_mem, strlen(PL_no_mem));
1163         my_exit(1);
1164     }
1165     Zero(thread, 1, ithread);
1166
1167     PL_perl_destruct_level = 2;
1168     MUTEX_INIT(&thread->mutex);
1169
1170     thread->tid = tid_counter++;        /* Thread 0 */
1171
1172     /* Head of the threads list */
1173     threads = thread;
1174     thread->next = thread;
1175     thread->prev = thread;
1176
1177     thread->count = 1;                  /* Immortal */
1178
1179     thread->interp = aTHX;
1180     thread->state = PERL_ITHR_DETACHED; /* Detached */
1181     thread->stack_size = default_stack_size;
1182 #  ifdef WIN32
1183     thread->thr = GetCurrentThreadId();
1184 #  else
1185     thread->thr = pthread_self();
1186 #  endif
1187
1188     active_threads++;
1189     joinable_threads++;
1190
1191     S_ithread_set(aTHX_ thread);
1192     MUTEX_UNLOCK(&create_destruct_mutex);
1193 #endif /* USE_ITHREADS */
1194 }