1 #define PERL_NO_GET_CONTEXT
6 # define NEED_newRV_noinc
7 # define NEED_sv_2pv_nolen
17 #include <win32thread.h>
20 typedef perl_os_thread pthread_t;
25 #define PERL_THREAD_SETSPECIFIC(k,v) pthread_setspecific(k,v)
26 #ifdef OLD_PTHREADS_API
27 #define PERL_THREAD_DETACH(t) pthread_detach(&(t))
29 #define PERL_THREAD_DETACH(t) pthread_detach((t))
30 #endif /* OLD_PTHREADS_API */
36 /* Values for 'state' member */
37 #define PERL_ITHR_JOINABLE 0
38 #define PERL_ITHR_DETACHED 1
39 #define PERL_ITHR_FINISHED 4
40 #define PERL_ITHR_JOINED 2
42 typedef struct ithread_s {
43 struct ithread_s *next; /* Next thread in the list */
44 struct ithread_s *prev; /* Prev thread in the list */
45 PerlInterpreter *interp; /* The threads interpreter */
46 I32 tid; /* Threads module's thread id */
47 perl_mutex mutex; /* Mutex for updating things in this struct */
48 I32 count; /* How many SVs have a reference to us */
49 signed char state; /* Are we detached ? */
50 int gimme; /* Context of create */
51 SV* init_function; /* Code to run */
52 SV* params; /* Args to pass function */
54 DWORD thr; /* OS's idea if thread id */
55 HANDLE handle; /* OS's waitable handle */
57 pthread_t thr; /* OS's handle for the thread */
61 #define MY_CXT_KEY "threads::_guts" XS_VERSION
72 /* Macros to supply the aTHX_ in an embed.h like manner */
73 #define ithread_join(thread) Perl_ithread_join(aTHX_ thread)
74 #define ithread_DESTROY(thread) Perl_ithread_DESTROY(aTHX_ thread)
75 #define ithread_CLONE(thread) Perl_ithread_CLONE(aTHX_ thread)
76 #define ithread_detach(thread) Perl_ithread_detach(aTHX_ thread)
77 #define ithread_tid(thread) ((thread)->tid)
78 #define ithread_yield(thread) (YIELD);
80 static perl_mutex create_destruct_mutex; /* protects the creation and destruction of threads*/
83 I32 known_threads = 0;
84 I32 active_threads = 0;
87 void Perl_ithread_set (pTHX_ ithread* thread)
90 MY_CXT.thread = thread;
93 ithread* Perl_ithread_get (pTHX) {
99 /* free any data (such as the perl interpreter) attached to an
100 * ithread structure. This is a bit like undef on SVs, where the SV
101 * isn't freed, but the PVX is.
102 * Must be called with thread->mutex already held
106 S_ithread_clear(pTHX_ ithread* thread)
108 PerlInterpreter *interp;
109 assert(thread->state & PERL_ITHR_FINISHED &&
110 (thread->state & PERL_ITHR_DETACHED ||
111 thread->state & PERL_ITHR_JOINED));
113 interp = thread->interp;
116 ithread* current_thread;
120 PERL_SET_CONTEXT(interp);
121 current_thread = Perl_ithread_get(aTHX);
122 Perl_ithread_set(aTHX_ thread);
124 SvREFCNT_dec(thread->params);
126 thread->params = Nullsv;
127 perl_destruct(interp);
128 thread->interp = NULL;
132 PERL_SET_CONTEXT(aTHX);
137 * free an ithread structure and any attached data if its count == 0
140 Perl_ithread_destruct (pTHX_ ithread* thread, const char *why)
142 MUTEX_LOCK(&thread->mutex);
144 MUTEX_UNLOCK(&thread->mutex);
145 Perl_croak(aTHX_ "panic: destruct destroyed thread %p (%s)",thread, why);
147 if (thread->count != 0) {
148 MUTEX_UNLOCK(&thread->mutex);
151 MUTEX_LOCK(&create_destruct_mutex);
152 /* Remove from circular list of threads */
153 if (thread->next == thread) {
154 /* last one should never get here ? */
158 thread->next->prev = thread->prev;
159 thread->prev->next = thread->next;
160 if (threads == thread) {
161 threads = thread->next;
167 assert( known_threads >= 0 );
169 Perl_warn(aTHX_ "destruct %d @ %p by %p now %d",
170 thread->tid,thread->interp,aTHX, known_threads);
172 MUTEX_UNLOCK(&create_destruct_mutex);
173 /* Thread is now disowned */
175 S_ithread_clear(aTHX_ thread);
177 MUTEX_UNLOCK(&thread->mutex);
178 MUTEX_DESTROY(&thread->mutex);
181 CloseHandle(thread->handle);
184 PerlMemShared_free(thread);
188 Perl_ithread_hook(pTHX)
190 int veto_cleanup = 0;
191 MUTEX_LOCK(&create_destruct_mutex);
192 if (aTHX == PL_curinterp && active_threads != 1) {
193 if (ckWARN_d(WARN_THREADS))
194 Perl_warn(aTHX_ "A thread exited while %" IVdf " threads were running",
198 MUTEX_UNLOCK(&create_destruct_mutex);
203 Perl_ithread_detach(pTHX_ ithread *thread)
205 MUTEX_LOCK(&thread->mutex);
206 if (!(thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED))) {
207 thread->state |= PERL_ITHR_DETACHED;
209 CloseHandle(thread->handle);
212 PERL_THREAD_DETACH(thread->thr);
215 if ((thread->state & PERL_ITHR_FINISHED) &&
216 (thread->state & PERL_ITHR_DETACHED)) {
217 MUTEX_UNLOCK(&thread->mutex);
218 Perl_ithread_destruct(aTHX_ thread, "detach");
221 MUTEX_UNLOCK(&thread->mutex);
225 /* MAGIC (in mg.h sense) hooks */
228 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
230 ithread *thread = (ithread *) mg->mg_ptr;
231 SvIV_set(sv, PTR2IV(thread));
237 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
239 ithread *thread = (ithread *) mg->mg_ptr;
240 MUTEX_LOCK(&thread->mutex);
242 if (thread->count == 0) {
243 if(thread->state & PERL_ITHR_FINISHED &&
244 (thread->state & PERL_ITHR_DETACHED ||
245 thread->state & PERL_ITHR_JOINED))
247 MUTEX_UNLOCK(&thread->mutex);
248 Perl_ithread_destruct(aTHX_ thread, "no reference");
251 MUTEX_UNLOCK(&thread->mutex);
255 MUTEX_UNLOCK(&thread->mutex);
261 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
263 ithread *thread = (ithread *) mg->mg_ptr;
264 MUTEX_LOCK(&thread->mutex);
266 MUTEX_UNLOCK(&thread->mutex);
270 MGVTBL ithread_vtbl = {
271 ithread_mg_get, /* get */
275 ithread_mg_free, /* free */
277 ithread_mg_dup /* dup */
282 * Starts executing the thread. Needs to clean up memory a tad better.
283 * Passed as the C level function to run in the new thread
288 Perl_ithread_run(LPVOID arg) {
291 Perl_ithread_run(void * arg) {
293 ithread* thread = (ithread*) arg;
294 dTHXa(thread->interp);
295 PERL_SET_CONTEXT(thread->interp);
296 Perl_ithread_set(aTHX_ thread);
299 /* Far from clear messing with ->thr child-side is a good idea */
300 MUTEX_LOCK(&thread->mutex);
302 thread->thr = GetCurrentThreadId();
304 thread->thr = pthread_self();
306 MUTEX_UNLOCK(&thread->mutex);
309 PL_perl_destruct_level = 2;
312 AV* params = (AV*) SvRV(thread->params);
313 I32 len = av_len(params)+1;
319 for(i = 0; i < len; i++) {
320 XPUSHs(av_shift(params));
323 len = call_sv(thread->init_function, thread->gimme|G_EVAL);
326 for (i=len-1; i >= 0; i--) {
328 av_store(params, i, SvREFCNT_inc(sv));
330 if (SvTRUE(ERRSV) && ckWARN_d(WARN_THREADS)) {
331 Perl_warn(aTHX_ "thread failed to start: %" SVf, ERRSV);
335 SvREFCNT_dec(thread->init_function);
338 PerlIO_flush((PerlIO*)NULL);
339 MUTEX_LOCK(&thread->mutex);
340 thread->state |= PERL_ITHR_FINISHED;
342 if (thread->state & PERL_ITHR_DETACHED) {
343 MUTEX_UNLOCK(&thread->mutex);
344 Perl_ithread_destruct(aTHX_ thread, "detached finish");
346 MUTEX_UNLOCK(&thread->mutex);
348 MUTEX_LOCK(&create_destruct_mutex);
350 assert( active_threads >= 0 );
351 MUTEX_UNLOCK(&create_destruct_mutex);
361 ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
366 MUTEX_LOCK(&thread->mutex);
368 MUTEX_UNLOCK(&thread->mutex);
372 sv = newSVrv(obj,classname);
373 sv_setiv(sv,PTR2IV(thread));
374 mg = sv_magicext(sv,Nullsv,PERL_MAGIC_shared_scalar,&ithread_vtbl,(char *)thread,0);
375 mg->mg_flags |= MGf_DUP;
381 SV_to_ithread(pTHX_ SV *sv)
385 return INT2PTR(ithread*, SvIV(SvRV(sv)));
389 return Perl_ithread_get(aTHX);
394 * ithread->create(); ( aka ithread->new() )
395 * Called in context of parent thread
399 Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* params)
402 CLONE_PARAMS clone_param;
403 ithread* current_thread = Perl_ithread_get(aTHX);
405 SV** tmps_tmp = PL_tmps_stack;
406 I32 tmps_ix = PL_tmps_ix;
409 const char* panic = NULL;
413 MUTEX_LOCK(&create_destruct_mutex);
414 thread = (ithread *) PerlMemShared_malloc(sizeof(ithread));
416 MUTEX_UNLOCK(&create_destruct_mutex);
417 PerlLIO_write(PerlIO_fileno(Perl_error_log),
418 PL_no_mem, strlen(PL_no_mem));
421 Zero(thread,1,ithread);
422 thread->next = threads;
423 thread->prev = threads->prev;
424 threads->prev = thread;
425 thread->prev->next = thread;
426 /* Set count to 1 immediately in case thread exits before
427 * we return to caller !
430 MUTEX_INIT(&thread->mutex);
431 thread->tid = tid_counter++;
432 thread->gimme = GIMME_V;
434 /* "Clone" our interpreter into the thread's interpreter
435 * This gives thread access to "static data" and code.
438 PerlIO_flush((PerlIO*)NULL);
439 Perl_ithread_set(aTHX_ thread);
441 SAVEBOOL(PL_srand_called); /* Save this so it becomes the correct
443 PL_srand_called = FALSE; /* Set it to false so we can detect
444 if it gets set during the clone */
447 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
449 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
451 /* perl_clone leaves us in new interpreter's context.
452 As it is tricky to spot an implicit aTHX, create a new scope
453 with aTHX matching the context for the duration of
454 our work for new interpreter.
457 dTHXa(thread->interp);
461 /* Here we remove END blocks since they should only run
462 in the thread they are created
464 SvREFCNT_dec(PL_endav);
466 clone_param.flags = 0;
467 thread->init_function = sv_dup(init_function, &clone_param);
468 if (SvREFCNT(thread->init_function) == 0) {
469 SvREFCNT_inc(thread->init_function);
474 thread->params = sv_dup(params, &clone_param);
475 SvREFCNT_inc(thread->params);
478 /* The code below checks that anything living on
479 the tmps stack and has been cloned (so it lives in the
480 ptr_table) has a refcount higher than 0
482 If the refcount is 0 it means that a something on the
483 stack/context was holding a reference to it and
484 since we init_stacks() in perl_clone that won't get
485 cleaned and we will get a leaked scalar.
486 The reason it was cloned was that it lived on the
489 Example of this can be found in bugreport 15837
490 where calls in the parameter list end up as a temp
492 One could argue that this fix should be in perl_clone
496 while (tmps_ix > 0) {
497 SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
499 if (sv && SvREFCNT(sv) == 0) {
507 SvTEMP_off(thread->init_function);
508 ptr_table_free(PL_ptr_table);
510 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
512 Perl_ithread_set(aTHX_ current_thread);
513 PERL_SET_CONTEXT(aTHX);
515 /* Start the thread */
518 thread->handle = CreateThread(NULL, 0, Perl_ithread_run,
519 (LPVOID)thread, 0, &thread->thr);
522 static pthread_attr_t attr;
523 static int attr_inited = 0;
524 static int attr_joinable = PTHREAD_CREATE_JOINABLE;
527 pthread_attr_init(&attr);
529 # ifdef PTHREAD_ATTR_SETDETACHSTATE
530 PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
532 # ifdef THREAD_CREATE_NEEDS_STACK
533 if(pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK))
534 panic = "panic: pthread_attr_setstacksize failed";
537 #ifdef OLD_PTHREADS_API
539 = panic ? 1 : pthread_create( &thread->thr, attr,
540 Perl_ithread_run, (void *)thread);
542 # if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
543 pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
546 = panic ? 1 : pthread_create( &thread->thr, &attr,
547 Perl_ithread_run, (void *)thread);
554 thread->handle == NULL
559 MUTEX_UNLOCK(&create_destruct_mutex);
561 Perl_ithread_destruct(aTHX_ thread, "create failed");
564 Perl_croak(aTHX_ panic);
569 MUTEX_UNLOCK(&create_destruct_mutex);
572 return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
576 Perl_ithread_self (pTHX_ SV *obj, char* Class)
578 ithread *thread = Perl_ithread_get(aTHX);
580 return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
582 Perl_croak(aTHX_ "panic: cannot find thread data");
583 return NULL; /* silence compiler warning */
587 * Joins the thread this code needs to take the returnvalue from the
588 * call_sv and send it back
592 Perl_ithread_CLONE(pTHX_ SV *obj)
595 ithread *thread = SV_to_ithread(aTHX_ obj);
597 else if (ckWARN_d(WARN_THREADS)) {
598 Perl_warn(aTHX_ "CLONE %" SVf,obj);
603 Perl_ithread_join(pTHX_ SV *obj)
605 ithread *thread = SV_to_ithread(aTHX_ obj);
606 MUTEX_LOCK(&thread->mutex);
607 if (thread->state & PERL_ITHR_DETACHED) {
608 MUTEX_UNLOCK(&thread->mutex);
609 Perl_croak(aTHX_ "Cannot join a detached thread");
611 else if (thread->state & PERL_ITHR_JOINED) {
612 MUTEX_UNLOCK(&thread->mutex);
613 Perl_croak(aTHX_ "Thread already joined");
622 MUTEX_UNLOCK(&thread->mutex);
624 waitcode = WaitForSingleObject(thread->handle, INFINITE);
625 CloseHandle(thread->handle);
628 pthread_join(thread->thr,&retval);
630 MUTEX_LOCK(&thread->mutex);
632 /* sv_dup over the args */
634 ithread* current_thread;
635 AV* params = (AV*) SvRV(thread->params);
636 PerlInterpreter *other_perl = thread->interp;
637 CLONE_PARAMS clone_params;
638 clone_params.stashes = newAV();
639 clone_params.flags = CLONEf_JOIN_IN;
640 PL_ptr_table = ptr_table_new();
641 current_thread = Perl_ithread_get(aTHX);
642 Perl_ithread_set(aTHX_ thread);
643 /* ensure 'meaningful' addresses retain their meaning */
644 ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
645 ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
646 ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
650 I32 len = av_len(params)+1;
652 for(i = 0; i < len; i++) {
653 sv_dump(SvRV(AvARRAY(params)[i]));
657 retparam = (AV*) sv_dup((SV*)params, &clone_params);
660 I32 len = av_len(retparam)+1;
662 for(i = 0; i < len; i++) {
663 sv_dump(SvRV(AvARRAY(retparam)[i]));
667 Perl_ithread_set(aTHX_ current_thread);
668 SvREFCNT_dec(clone_params.stashes);
669 SvREFCNT_inc(retparam);
670 ptr_table_free(PL_ptr_table);
674 /* We are finished with it */
675 thread->state |= PERL_ITHR_JOINED;
676 S_ithread_clear(aTHX_ thread);
677 MUTEX_UNLOCK(&thread->mutex);
685 Perl_ithread_DESTROY(pTHX_ SV *sv)
687 ithread *thread = SV_to_ithread(aTHX_ sv);
688 sv_unmagic(SvRV(sv),PERL_MAGIC_shared_scalar);
691 #endif /* USE_ITHREADS */
693 MODULE = threads PACKAGE = threads PREFIX = ithread_
699 ithread_new (classname, function_to_call, ...)
701 SV * function_to_call
704 AV* params = newAV();
707 for(i = 2; i < items ; i++) {
708 av_push(params, SvREFCNT_inc(ST(i)));
711 ST(0) = sv_2mortal(Perl_ithread_create(aTHX_ Nullsv, classname, function_to_call, newRV_noinc((SV*) params)));
716 ithread_list(char *classname)
719 ithread *curr_thread;
720 MUTEX_LOCK(&create_destruct_mutex);
721 curr_thread = threads;
722 if(curr_thread->tid != 0)
723 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
725 curr_thread = curr_thread->next;
726 if(curr_thread == threads)
728 if(curr_thread->state & PERL_ITHR_DETACHED ||
729 curr_thread->state & PERL_ITHR_JOINED)
731 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
733 MUTEX_UNLOCK(&create_destruct_mutex);
738 ithread_self(char *classname)
741 ST(0) = sv_2mortal(Perl_ithread_self(aTHX_ Nullsv,classname));
746 ithread_tid(ithread *thread)
749 ithread_join(SV *obj)
752 AV* params = Perl_ithread_join(aTHX_ obj);
754 I32 len = AvFILL(params);
755 for (i = 0; i <= len; i++) {
756 SV* tmp = av_shift(params);
760 SvREFCNT_dec(params);
772 ithread_detach(ithread *thread)
775 ithread_DESTROY(SV *thread)
777 #endif /* USE_ITHREADS */
784 PL_perl_destruct_level = 2;
785 MUTEX_INIT(&create_destruct_mutex);
786 MUTEX_LOCK(&create_destruct_mutex);
787 PL_threadhook = &Perl_ithread_hook;
788 thread = (ithread *) PerlMemShared_malloc(sizeof(ithread));
790 PerlLIO_write(PerlIO_fileno(Perl_error_log),
791 PL_no_mem, strlen(PL_no_mem));
794 Zero(thread,1,ithread);
795 PL_perl_destruct_level = 2;
796 MUTEX_INIT(&thread->mutex);
798 thread->next = thread;
799 thread->prev = thread;
800 thread->interp = aTHX;
801 thread->count = 1; /* Immortal. */
802 thread->tid = tid_counter++;
805 thread->state = PERL_ITHR_DETACHED;
807 thread->thr = GetCurrentThreadId();
809 thread->thr = pthread_self();
812 Perl_ithread_set(aTHX_ thread);
813 MUTEX_UNLOCK(&create_destruct_mutex);
814 #endif /* USE_ITHREADS */