1 #define PERL_NO_GET_CONTEXT
11 #include <win32thread.h>
14 typedef perl_os_thread pthread_t;
19 #define PERL_THREAD_SETSPECIFIC(k,v) pthread_setspecific(k,v)
20 #ifdef OLD_PTHREADS_API
21 #define PERL_THREAD_DETACH(t) pthread_detach(&(t))
23 #define PERL_THREAD_DETACH(t) pthread_detach((t))
24 #endif /* OLD_PTHREADS_API */
30 /* Values for 'state' member */
31 #define PERL_ITHR_JOINABLE 0
32 #define PERL_ITHR_DETACHED 1
33 #define PERL_ITHR_FINISHED 4
34 #define PERL_ITHR_JOINED 2
36 typedef struct ithread_s {
37 struct ithread_s *next; /* Next thread in the list */
38 struct ithread_s *prev; /* Prev thread in the list */
39 PerlInterpreter *interp; /* The threads interpreter */
40 I32 tid; /* Threads module's thread id */
41 perl_mutex mutex; /* Mutex for updating things in this struct */
42 I32 count; /* How many SVs have a reference to us */
43 signed char state; /* Are we detached ? */
44 int gimme; /* Context of create */
45 SV* init_function; /* Code to run */
46 SV* params; /* Args to pass function */
48 DWORD thr; /* OS's idea if thread id */
49 HANDLE handle; /* OS's waitable handle */
51 pthread_t thr; /* OS's handle for the thread */
57 /* Macros to supply the aTHX_ in an embed.h like manner */
58 #define ithread_join(thread) Perl_ithread_join(aTHX_ thread)
59 #define ithread_DESTROY(thread) Perl_ithread_DESTROY(aTHX_ thread)
60 #define ithread_CLONE(thread) Perl_ithread_CLONE(aTHX_ thread)
61 #define ithread_detach(thread) Perl_ithread_detach(aTHX_ thread)
62 #define ithread_tid(thread) ((thread)->tid)
63 #define ithread_yield(thread) (YIELD);
65 static perl_mutex create_destruct_mutex; /* protects the creation and destruction of threads*/
68 I32 known_threads = 0;
69 I32 active_threads = 0;
72 void Perl_ithread_set (pTHX_ ithread* thread)
74 SV* thread_sv = newSViv(PTR2IV(thread));
75 if(!hv_store(PL_modglobal, "threads::self", 12, thread_sv,0)) {
76 croak("%s\n","Internal error, couldn't set TLS");
80 ithread* Perl_ithread_get (pTHX) {
81 SV** thread_sv = hv_fetch(PL_modglobal, "threads::self",12,0);
83 croak("%s\n","Internal error, couldn't get TLS");
85 return INT2PTR(ithread*,SvIV(*thread_sv));
91 * Clear up after thread is done with
94 Perl_ithread_destruct (pTHX_ ithread* thread, const char *why)
96 PerlInterpreter *freeperl = NULL;
97 MUTEX_LOCK(&thread->mutex);
99 MUTEX_UNLOCK(&thread->mutex);
100 Perl_croak(aTHX_ "panic: destruct destroyed thread %p (%s)",thread, why);
102 if (thread->count != 0) {
103 MUTEX_UNLOCK(&thread->mutex);
106 MUTEX_LOCK(&create_destruct_mutex);
107 /* Remove from circular list of threads */
108 if (thread->next == thread) {
109 /* last one should never get here ? */
113 thread->next->prev = thread->prev;
114 thread->prev->next = thread->next;
115 if (threads == thread) {
116 threads = thread->next;
122 assert( known_threads >= 0 );
124 Perl_warn(aTHX_ "destruct %d @ %p by %p now %d",
125 thread->tid,thread->interp,aTHX, known_threads);
127 MUTEX_UNLOCK(&create_destruct_mutex);
128 /* Thread is now disowned */
131 dTHXa(thread->interp);
132 ithread* current_thread;
136 PERL_SET_CONTEXT(thread->interp);
137 current_thread = Perl_ithread_get(aTHX);
138 Perl_ithread_set(aTHX_ thread);
143 SvREFCNT_dec(thread->params);
147 thread->params = Nullsv;
148 perl_destruct(thread->interp);
149 freeperl = thread->interp;
150 thread->interp = NULL;
152 MUTEX_UNLOCK(&thread->mutex);
153 MUTEX_DESTROY(&thread->mutex);
156 CloseHandle(thread->handle);
159 PerlMemShared_free(thread);
163 PERL_SET_CONTEXT(aTHX);
167 Perl_ithread_hook(pTHX)
169 int veto_cleanup = 0;
170 MUTEX_LOCK(&create_destruct_mutex);
171 if (aTHX == PL_curinterp && active_threads != 1) {
172 if (ckWARN_d(WARN_THREADS))
173 Perl_warn(aTHX_ "A thread exited while %" IVdf " threads were running",
177 MUTEX_UNLOCK(&create_destruct_mutex);
182 Perl_ithread_detach(pTHX_ ithread *thread)
184 MUTEX_LOCK(&thread->mutex);
185 if (!(thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED))) {
186 thread->state |= PERL_ITHR_DETACHED;
188 CloseHandle(thread->handle);
191 PERL_THREAD_DETACH(thread->thr);
194 if ((thread->state & PERL_ITHR_FINISHED) &&
195 (thread->state & PERL_ITHR_DETACHED)) {
196 MUTEX_UNLOCK(&thread->mutex);
197 Perl_ithread_destruct(aTHX_ thread, "detach");
200 MUTEX_UNLOCK(&thread->mutex);
204 /* MAGIC (in mg.h sense) hooks */
207 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
209 ithread *thread = (ithread *) mg->mg_ptr;
210 SvIV_set(sv, PTR2IV(thread));
216 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
218 ithread *thread = (ithread *) mg->mg_ptr;
219 MUTEX_LOCK(&thread->mutex);
221 if (thread->count == 0) {
222 if(thread->state & PERL_ITHR_FINISHED &&
223 (thread->state & PERL_ITHR_DETACHED ||
224 thread->state & PERL_ITHR_JOINED))
226 MUTEX_UNLOCK(&thread->mutex);
227 Perl_ithread_destruct(aTHX_ thread, "no reference");
230 MUTEX_UNLOCK(&thread->mutex);
234 MUTEX_UNLOCK(&thread->mutex);
240 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
242 ithread *thread = (ithread *) mg->mg_ptr;
243 MUTEX_LOCK(&thread->mutex);
245 MUTEX_UNLOCK(&thread->mutex);
249 MGVTBL ithread_vtbl = {
250 ithread_mg_get, /* get */
254 ithread_mg_free, /* free */
256 ithread_mg_dup /* dup */
261 * Starts executing the thread. Needs to clean up memory a tad better.
262 * Passed as the C level function to run in the new thread
267 Perl_ithread_run(LPVOID arg) {
270 Perl_ithread_run(void * arg) {
272 ithread* thread = (ithread*) arg;
273 dTHXa(thread->interp);
274 PERL_SET_CONTEXT(thread->interp);
275 Perl_ithread_set(aTHX_ thread);
278 /* Far from clear messing with ->thr child-side is a good idea */
279 MUTEX_LOCK(&thread->mutex);
281 thread->thr = GetCurrentThreadId();
283 thread->thr = pthread_self();
285 MUTEX_UNLOCK(&thread->mutex);
288 PL_perl_destruct_level = 2;
291 AV* params = (AV*) SvRV(thread->params);
292 I32 len = av_len(params)+1;
298 for(i = 0; i < len; i++) {
299 XPUSHs(av_shift(params));
302 len = call_sv(thread->init_function, thread->gimme|G_EVAL);
305 for (i=len-1; i >= 0; i--) {
307 av_store(params, i, SvREFCNT_inc(sv));
309 if (SvTRUE(ERRSV) && ckWARN_d(WARN_THREADS)) {
310 Perl_warn(aTHX_ "thread failed to start: %" SVf, ERRSV);
314 SvREFCNT_dec(thread->init_function);
317 PerlIO_flush((PerlIO*)NULL);
318 MUTEX_LOCK(&thread->mutex);
319 thread->state |= PERL_ITHR_FINISHED;
321 if (thread->state & PERL_ITHR_DETACHED) {
322 MUTEX_UNLOCK(&thread->mutex);
323 Perl_ithread_destruct(aTHX_ thread, "detached finish");
325 MUTEX_UNLOCK(&thread->mutex);
327 MUTEX_LOCK(&create_destruct_mutex);
329 assert( active_threads >= 0 );
330 MUTEX_UNLOCK(&create_destruct_mutex);
340 ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
345 MUTEX_LOCK(&thread->mutex);
347 MUTEX_UNLOCK(&thread->mutex);
351 sv = newSVrv(obj,classname);
352 sv_setiv(sv,PTR2IV(thread));
353 mg = sv_magicext(sv,Nullsv,PERL_MAGIC_shared_scalar,&ithread_vtbl,(char *)thread,0);
354 mg->mg_flags |= MGf_DUP;
360 SV_to_ithread(pTHX_ SV *sv)
364 return INT2PTR(ithread*, SvIV(SvRV(sv)));
368 return Perl_ithread_get(aTHX);
373 * ithread->create(); ( aka ithread->new() )
374 * Called in context of parent thread
378 Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* params)
381 CLONE_PARAMS clone_param;
382 ithread* current_thread = Perl_ithread_get(aTHX);
384 SV** tmps_tmp = PL_tmps_stack;
385 I32 tmps_ix = PL_tmps_ix;
388 const char* panic = NULL;
392 MUTEX_LOCK(&create_destruct_mutex);
393 thread = (ithread *) PerlMemShared_malloc(sizeof(ithread));
395 MUTEX_UNLOCK(&create_destruct_mutex);
396 PerlLIO_write(PerlIO_fileno(Perl_error_log),
397 PL_no_mem, strlen(PL_no_mem));
400 Zero(thread,1,ithread);
401 thread->next = threads;
402 thread->prev = threads->prev;
403 threads->prev = thread;
404 thread->prev->next = thread;
405 /* Set count to 1 immediately in case thread exits before
406 * we return to caller !
409 MUTEX_INIT(&thread->mutex);
410 thread->tid = tid_counter++;
411 thread->gimme = GIMME_V;
413 /* "Clone" our interpreter into the thread's interpreter
414 * This gives thread access to "static data" and code.
417 PerlIO_flush((PerlIO*)NULL);
418 Perl_ithread_set(aTHX_ thread);
420 SAVEBOOL(PL_srand_called); /* Save this so it becomes the correct
422 PL_srand_called = FALSE; /* Set it to false so we can detect
423 if it gets set during the clone */
426 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
428 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
430 /* perl_clone leaves us in new interpreter's context.
431 As it is tricky to spot an implicit aTHX, create a new scope
432 with aTHX matching the context for the duration of
433 our work for new interpreter.
436 dTHXa(thread->interp);
438 /* Here we remove END blocks since they should only run
439 in the thread they are created
441 SvREFCNT_dec(PL_endav);
443 clone_param.flags = 0;
444 thread->init_function = sv_dup(init_function, &clone_param);
445 if (SvREFCNT(thread->init_function) == 0) {
446 SvREFCNT_inc(thread->init_function);
451 thread->params = sv_dup(params, &clone_param);
452 SvREFCNT_inc(thread->params);
455 /* The code below checks that anything living on
456 the tmps stack and has been cloned (so it lives in the
457 ptr_table) has a refcount higher than 0
459 If the refcount is 0 it means that a something on the
460 stack/context was holding a reference to it and
461 since we init_stacks() in perl_clone that won't get
462 cleaned and we will get a leaked scalar.
463 The reason it was cloned was that it lived on the
466 Example of this can be found in bugreport 15837
467 where calls in the parameter list end up as a temp
469 One could argue that this fix should be in perl_clone
473 while (tmps_ix > 0) {
474 SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
476 if (sv && SvREFCNT(sv) == 0) {
484 SvTEMP_off(thread->init_function);
485 ptr_table_free(PL_ptr_table);
487 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
489 Perl_ithread_set(aTHX_ current_thread);
490 PERL_SET_CONTEXT(aTHX);
492 /* Start the thread */
495 thread->handle = CreateThread(NULL, 0, Perl_ithread_run,
496 (LPVOID)thread, 0, &thread->thr);
499 static pthread_attr_t attr;
500 static int attr_inited = 0;
501 static int attr_joinable = PTHREAD_CREATE_JOINABLE;
504 pthread_attr_init(&attr);
506 # ifdef PTHREAD_ATTR_SETDETACHSTATE
507 PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
509 # ifdef THREAD_CREATE_NEEDS_STACK
510 if(pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK))
511 panic = "panic: pthread_attr_setstacksize failed";
514 #ifdef OLD_PTHREADS_API
516 = panic ? 1 : pthread_create( &thread->thr, attr,
517 Perl_ithread_run, (void *)thread);
519 # if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
520 pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
523 = panic ? 1 : pthread_create( &thread->thr, &attr,
524 Perl_ithread_run, (void *)thread);
531 thread->handle == NULL
536 MUTEX_UNLOCK(&create_destruct_mutex);
538 Perl_ithread_destruct(aTHX_ thread, "create failed");
541 Perl_croak(aTHX_ panic);
546 MUTEX_UNLOCK(&create_destruct_mutex);
549 return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
553 Perl_ithread_self (pTHX_ SV *obj, char* Class)
555 ithread *thread = Perl_ithread_get(aTHX);
557 return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
559 Perl_croak(aTHX_ "panic: cannot find thread data");
560 return NULL; /* silence compiler warning */
564 * Joins the thread this code needs to take the returnvalue from the
565 * call_sv and send it back
569 Perl_ithread_CLONE(pTHX_ SV *obj)
572 ithread *thread = SV_to_ithread(aTHX_ obj);
574 else if (ckWARN_d(WARN_THREADS)) {
575 Perl_warn(aTHX_ "CLONE %" SVf,obj);
580 Perl_ithread_join(pTHX_ SV *obj)
582 ithread *thread = SV_to_ithread(aTHX_ obj);
583 MUTEX_LOCK(&thread->mutex);
584 if (thread->state & PERL_ITHR_DETACHED) {
585 MUTEX_UNLOCK(&thread->mutex);
586 Perl_croak(aTHX_ "Cannot join a detached thread");
588 else if (thread->state & PERL_ITHR_JOINED) {
589 MUTEX_UNLOCK(&thread->mutex);
590 Perl_croak(aTHX_ "Thread already joined");
599 MUTEX_UNLOCK(&thread->mutex);
601 waitcode = WaitForSingleObject(thread->handle, INFINITE);
602 CloseHandle(thread->handle);
605 pthread_join(thread->thr,&retval);
607 MUTEX_LOCK(&thread->mutex);
609 /* sv_dup over the args */
611 ithread* current_thread;
612 AV* params = (AV*) SvRV(thread->params);
613 PerlInterpreter *other_perl = thread->interp;
614 CLONE_PARAMS clone_params;
615 clone_params.stashes = newAV();
616 clone_params.flags |= CLONEf_JOIN_IN;
617 PL_ptr_table = ptr_table_new();
618 current_thread = Perl_ithread_get(aTHX);
619 Perl_ithread_set(aTHX_ thread);
620 /* ensure 'meaningful' addresses retain their meaning */
621 ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
622 ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
623 ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
627 I32 len = av_len(params)+1;
629 for(i = 0; i < len; i++) {
630 sv_dump(SvRV(AvARRAY(params)[i]));
634 retparam = (AV*) sv_dup((SV*)params, &clone_params);
637 I32 len = av_len(retparam)+1;
639 for(i = 0; i < len; i++) {
640 sv_dump(SvRV(AvARRAY(retparam)[i]));
644 Perl_ithread_set(aTHX_ current_thread);
645 SvREFCNT_dec(clone_params.stashes);
646 SvREFCNT_inc(retparam);
647 ptr_table_free(PL_ptr_table);
651 /* We are finished with it */
652 thread->state |= PERL_ITHR_JOINED;
653 MUTEX_UNLOCK(&thread->mutex);
661 Perl_ithread_DESTROY(pTHX_ SV *sv)
663 ithread *thread = SV_to_ithread(aTHX_ sv);
664 sv_unmagic(SvRV(sv),PERL_MAGIC_shared_scalar);
667 #endif /* USE_ITHREADS */
669 MODULE = threads PACKAGE = threads PREFIX = ithread_
675 ithread_new (classname, function_to_call, ...)
677 SV * function_to_call
680 AV* params = newAV();
683 for(i = 2; i < items ; i++) {
684 av_push(params, SvREFCNT_inc(ST(i)));
687 ST(0) = sv_2mortal(Perl_ithread_create(aTHX_ Nullsv, classname, function_to_call, newRV_noinc((SV*) params)));
692 ithread_list(char *classname)
695 ithread *curr_thread;
696 MUTEX_LOCK(&create_destruct_mutex);
697 curr_thread = threads;
698 if(curr_thread->tid != 0)
699 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
701 curr_thread = curr_thread->next;
702 if(curr_thread == threads)
704 if(curr_thread->state & PERL_ITHR_DETACHED ||
705 curr_thread->state & PERL_ITHR_JOINED)
707 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
709 MUTEX_UNLOCK(&create_destruct_mutex);
714 ithread_self(char *classname)
717 ST(0) = sv_2mortal(Perl_ithread_self(aTHX_ Nullsv,classname));
722 ithread_tid(ithread *thread)
725 ithread_join(SV *obj)
728 AV* params = Perl_ithread_join(aTHX_ obj);
730 I32 len = AvFILL(params);
731 for (i = 0; i <= len; i++) {
732 SV* tmp = av_shift(params);
736 SvREFCNT_dec(params);
748 ithread_detach(ithread *thread)
751 ithread_DESTROY(SV *thread)
753 #endif /* USE_ITHREADS */
759 PL_perl_destruct_level = 2;
760 MUTEX_INIT(&create_destruct_mutex);
761 MUTEX_LOCK(&create_destruct_mutex);
762 PL_threadhook = &Perl_ithread_hook;
763 thread = (ithread *) PerlMemShared_malloc(sizeof(ithread));
765 PerlLIO_write(PerlIO_fileno(Perl_error_log),
766 PL_no_mem, strlen(PL_no_mem));
769 Zero(thread,1,ithread);
770 PL_perl_destruct_level = 2;
771 MUTEX_INIT(&thread->mutex);
773 thread->next = thread;
774 thread->prev = thread;
775 thread->interp = aTHX;
776 thread->count = 1; /* Immortal. */
777 thread->tid = tid_counter++;
780 thread->state = PERL_ITHR_DETACHED;
782 thread->thr = GetCurrentThreadId();
784 thread->thr = pthread_self();
787 Perl_ithread_set(aTHX_ thread);
788 MUTEX_UNLOCK(&create_destruct_mutex);
789 #endif /* USE_ITHREADS */