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 Perl_croak(aTHX_ "panic: destruct destroyed thread %p (%s)",thread, why);
101 if (thread->count != 0) {
102 MUTEX_UNLOCK(&thread->mutex);
105 MUTEX_LOCK(&create_destruct_mutex);
106 /* Remove from circular list of threads */
107 if (thread->next == thread) {
108 /* last one should never get here ? */
112 thread->next->prev = thread->prev;
113 thread->prev->next = thread->next;
114 if (threads == thread) {
115 threads = thread->next;
121 assert( known_threads >= 0 );
123 Perl_warn(aTHX_ "destruct %d @ %p by %p now %d",
124 thread->tid,thread->interp,aTHX, known_threads);
126 MUTEX_UNLOCK(&create_destruct_mutex);
127 /* Thread is now disowned */
130 dTHXa(thread->interp);
131 ithread* current_thread;
135 PERL_SET_CONTEXT(thread->interp);
136 current_thread = Perl_ithread_get(aTHX);
137 Perl_ithread_set(aTHX_ thread);
142 SvREFCNT_dec(thread->params);
146 thread->params = Nullsv;
147 perl_destruct(thread->interp);
148 freeperl = thread->interp;
149 thread->interp = NULL;
151 MUTEX_UNLOCK(&thread->mutex);
152 MUTEX_DESTROY(&thread->mutex);
155 CloseHandle(thread->handle);
158 PerlMemShared_free(thread);
162 PERL_SET_CONTEXT(aTHX);
166 Perl_ithread_hook(pTHX)
168 int veto_cleanup = 0;
169 MUTEX_LOCK(&create_destruct_mutex);
170 if (aTHX == PL_curinterp && active_threads != 1) {
171 if (ckWARN_d(WARN_THREADS))
172 Perl_warn(aTHX_ "A thread exited while %" IVdf " threads were running",
176 MUTEX_UNLOCK(&create_destruct_mutex);
181 Perl_ithread_detach(pTHX_ ithread *thread)
183 MUTEX_LOCK(&thread->mutex);
184 if (!(thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED))) {
185 thread->state |= PERL_ITHR_DETACHED;
187 CloseHandle(thread->handle);
190 PERL_THREAD_DETACH(thread->thr);
193 if ((thread->state & PERL_ITHR_FINISHED) &&
194 (thread->state & PERL_ITHR_DETACHED)) {
195 MUTEX_UNLOCK(&thread->mutex);
196 Perl_ithread_destruct(aTHX_ thread, "detach");
199 MUTEX_UNLOCK(&thread->mutex);
203 /* MAGIC (in mg.h sense) hooks */
206 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
208 ithread *thread = (ithread *) mg->mg_ptr;
209 SvIV_set(sv, PTR2IV(thread));
215 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
217 ithread *thread = (ithread *) mg->mg_ptr;
218 MUTEX_LOCK(&thread->mutex);
220 if (thread->count == 0) {
221 if(thread->state & PERL_ITHR_FINISHED &&
222 (thread->state & PERL_ITHR_DETACHED ||
223 thread->state & PERL_ITHR_JOINED))
225 MUTEX_UNLOCK(&thread->mutex);
226 Perl_ithread_destruct(aTHX_ thread, "no reference");
229 MUTEX_UNLOCK(&thread->mutex);
233 MUTEX_UNLOCK(&thread->mutex);
239 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
241 ithread *thread = (ithread *) mg->mg_ptr;
242 MUTEX_LOCK(&thread->mutex);
244 MUTEX_UNLOCK(&thread->mutex);
248 MGVTBL ithread_vtbl = {
249 ithread_mg_get, /* get */
253 ithread_mg_free, /* free */
255 ithread_mg_dup /* dup */
260 * Starts executing the thread. Needs to clean up memory a tad better.
261 * Passed as the C level function to run in the new thread
266 Perl_ithread_run(LPVOID arg) {
269 Perl_ithread_run(void * arg) {
271 ithread* thread = (ithread*) arg;
272 dTHXa(thread->interp);
273 PERL_SET_CONTEXT(thread->interp);
274 Perl_ithread_set(aTHX_ thread);
277 /* Far from clear messing with ->thr child-side is a good idea */
278 MUTEX_LOCK(&thread->mutex);
280 thread->thr = GetCurrentThreadId();
282 thread->thr = pthread_self();
284 MUTEX_UNLOCK(&thread->mutex);
287 PL_perl_destruct_level = 2;
290 AV* params = (AV*) SvRV(thread->params);
291 I32 len = av_len(params)+1;
297 for(i = 0; i < len; i++) {
298 XPUSHs(av_shift(params));
301 len = call_sv(thread->init_function, thread->gimme|G_EVAL);
304 for (i=len-1; i >= 0; i--) {
306 av_store(params, i, SvREFCNT_inc(sv));
308 if (SvTRUE(ERRSV) && ckWARN_d(WARN_THREADS)) {
309 Perl_warn(aTHX_ "thread failed to start: %" SVf, ERRSV);
313 SvREFCNT_dec(thread->init_function);
316 PerlIO_flush((PerlIO*)NULL);
317 MUTEX_LOCK(&thread->mutex);
318 thread->state |= PERL_ITHR_FINISHED;
320 if (thread->state & PERL_ITHR_DETACHED) {
321 MUTEX_UNLOCK(&thread->mutex);
322 Perl_ithread_destruct(aTHX_ thread, "detached finish");
324 MUTEX_UNLOCK(&thread->mutex);
326 MUTEX_LOCK(&create_destruct_mutex);
328 assert( active_threads >= 0 );
329 MUTEX_UNLOCK(&create_destruct_mutex);
339 ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
344 MUTEX_LOCK(&thread->mutex);
346 MUTEX_UNLOCK(&thread->mutex);
350 sv = newSVrv(obj,classname);
351 sv_setiv(sv,PTR2IV(thread));
352 mg = sv_magicext(sv,Nullsv,PERL_MAGIC_shared_scalar,&ithread_vtbl,(char *)thread,0);
353 mg->mg_flags |= MGf_DUP;
359 SV_to_ithread(pTHX_ SV *sv)
363 return INT2PTR(ithread*, SvIV(SvRV(sv)));
367 return Perl_ithread_get(aTHX);
372 * ithread->create(); ( aka ithread->new() )
373 * Called in context of parent thread
377 Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* params)
380 CLONE_PARAMS clone_param;
381 ithread* current_thread = Perl_ithread_get(aTHX);
383 SV** tmps_tmp = PL_tmps_stack;
384 I32 tmps_ix = PL_tmps_ix;
387 const char* panic = NULL;
391 MUTEX_LOCK(&create_destruct_mutex);
392 thread = (ithread *) PerlMemShared_malloc(sizeof(ithread));
394 MUTEX_UNLOCK(&create_destruct_mutex);
395 PerlLIO_write(PerlIO_fileno(Perl_error_log),
396 PL_no_mem, strlen(PL_no_mem));
399 Zero(thread,1,ithread);
400 thread->next = threads;
401 thread->prev = threads->prev;
402 threads->prev = thread;
403 thread->prev->next = thread;
404 /* Set count to 1 immediately in case thread exits before
405 * we return to caller !
408 MUTEX_INIT(&thread->mutex);
409 thread->tid = tid_counter++;
410 thread->gimme = GIMME_V;
412 /* "Clone" our interpreter into the thread's interpreter
413 * This gives thread access to "static data" and code.
416 PerlIO_flush((PerlIO*)NULL);
417 Perl_ithread_set(aTHX_ thread);
419 SAVEBOOL(PL_srand_called); /* Save this so it becomes the correct
421 PL_srand_called = FALSE; /* Set it to false so we can detect
422 if it gets set during the clone */
425 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
427 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
429 /* perl_clone leaves us in new interpreter's context.
430 As it is tricky to spot an implicit aTHX, create a new scope
431 with aTHX matching the context for the duration of
432 our work for new interpreter.
435 dTHXa(thread->interp);
437 /* Here we remove END blocks since they should only run
438 in the thread they are created
440 SvREFCNT_dec(PL_endav);
442 clone_param.flags = 0;
443 thread->init_function = sv_dup(init_function, &clone_param);
444 if (SvREFCNT(thread->init_function) == 0) {
445 SvREFCNT_inc(thread->init_function);
450 thread->params = sv_dup(params, &clone_param);
451 SvREFCNT_inc(thread->params);
454 /* The code below checks that anything living on
455 the tmps stack and has been cloned (so it lives in the
456 ptr_table) has a refcount higher than 0
458 If the refcount is 0 it means that a something on the
459 stack/context was holding a reference to it and
460 since we init_stacks() in perl_clone that won't get
461 cleaned and we will get a leaked scalar.
462 The reason it was cloned was that it lived on the
465 Example of this can be found in bugreport 15837
466 where calls in the parameter list end up as a temp
468 One could argue that this fix should be in perl_clone
472 while (tmps_ix > 0) {
473 SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
475 if (sv && SvREFCNT(sv) == 0) {
483 SvTEMP_off(thread->init_function);
484 ptr_table_free(PL_ptr_table);
486 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
488 Perl_ithread_set(aTHX_ current_thread);
489 PERL_SET_CONTEXT(aTHX);
491 /* Start the thread */
494 thread->handle = CreateThread(NULL, 0, Perl_ithread_run,
495 (LPVOID)thread, 0, &thread->thr);
498 static pthread_attr_t attr;
499 static int attr_inited = 0;
500 static int attr_joinable = PTHREAD_CREATE_JOINABLE;
503 pthread_attr_init(&attr);
505 # ifdef PTHREAD_ATTR_SETDETACHSTATE
506 PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
508 # ifdef THREAD_CREATE_NEEDS_STACK
509 if(pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK))
510 panic = "panic: pthread_attr_setstacksize failed";
513 #ifdef OLD_PTHREADS_API
515 = panic ? 1 : pthread_create( &thread->thr, attr,
516 Perl_ithread_run, (void *)thread);
518 # if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
519 pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
522 = panic ? 1 : pthread_create( &thread->thr, &attr,
523 Perl_ithread_run, (void *)thread);
530 thread->handle == NULL
535 MUTEX_UNLOCK(&create_destruct_mutex);
537 Perl_ithread_destruct(aTHX_ thread, "create failed");
540 Perl_croak(aTHX_ panic);
545 MUTEX_UNLOCK(&create_destruct_mutex);
548 return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
552 Perl_ithread_self (pTHX_ SV *obj, char* Class)
554 ithread *thread = Perl_ithread_get(aTHX);
556 return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
558 Perl_croak(aTHX_ "panic: cannot find thread data");
559 return NULL; /* silence compiler warning */
563 * Joins the thread this code needs to take the returnvalue from the
564 * call_sv and send it back
568 Perl_ithread_CLONE(pTHX_ SV *obj)
571 ithread *thread = SV_to_ithread(aTHX_ obj);
573 else if (ckWARN_d(WARN_THREADS)) {
574 Perl_warn(aTHX_ "CLONE %" SVf,obj);
579 Perl_ithread_join(pTHX_ SV *obj)
581 ithread *thread = SV_to_ithread(aTHX_ obj);
582 MUTEX_LOCK(&thread->mutex);
583 if (thread->state & PERL_ITHR_DETACHED) {
584 MUTEX_UNLOCK(&thread->mutex);
585 Perl_croak(aTHX_ "Cannot join a detached thread");
587 else if (thread->state & PERL_ITHR_JOINED) {
588 MUTEX_UNLOCK(&thread->mutex);
589 Perl_croak(aTHX_ "Thread already joined");
598 MUTEX_UNLOCK(&thread->mutex);
600 waitcode = WaitForSingleObject(thread->handle, INFINITE);
601 CloseHandle(thread->handle);
604 pthread_join(thread->thr,&retval);
606 MUTEX_LOCK(&thread->mutex);
608 /* sv_dup over the args */
610 ithread* current_thread;
611 AV* params = (AV*) SvRV(thread->params);
612 PerlInterpreter *other_perl = thread->interp;
613 CLONE_PARAMS clone_params;
614 clone_params.stashes = newAV();
615 clone_params.flags |= CLONEf_JOIN_IN;
616 PL_ptr_table = ptr_table_new();
617 current_thread = Perl_ithread_get(aTHX);
618 Perl_ithread_set(aTHX_ thread);
619 /* ensure 'meaningful' addresses retain their meaning */
620 ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
621 ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
622 ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
626 I32 len = av_len(params)+1;
628 for(i = 0; i < len; i++) {
629 sv_dump(SvRV(AvARRAY(params)[i]));
633 retparam = (AV*) sv_dup((SV*)params, &clone_params);
636 I32 len = av_len(retparam)+1;
638 for(i = 0; i < len; i++) {
639 sv_dump(SvRV(AvARRAY(retparam)[i]));
643 Perl_ithread_set(aTHX_ current_thread);
644 SvREFCNT_dec(clone_params.stashes);
645 SvREFCNT_inc(retparam);
646 ptr_table_free(PL_ptr_table);
650 /* We are finished with it */
651 thread->state |= PERL_ITHR_JOINED;
652 MUTEX_UNLOCK(&thread->mutex);
660 Perl_ithread_DESTROY(pTHX_ SV *sv)
662 ithread *thread = SV_to_ithread(aTHX_ sv);
663 sv_unmagic(SvRV(sv),PERL_MAGIC_shared_scalar);
666 #endif /* USE_ITHREADS */
668 MODULE = threads PACKAGE = threads PREFIX = ithread_
674 ithread_new (classname, function_to_call, ...)
676 SV * function_to_call
679 AV* params = newAV();
682 for(i = 2; i < items ; i++) {
683 av_push(params, SvREFCNT_inc(ST(i)));
686 ST(0) = sv_2mortal(Perl_ithread_create(aTHX_ Nullsv, classname, function_to_call, newRV_noinc((SV*) params)));
691 ithread_list(char *classname)
694 ithread *curr_thread;
695 MUTEX_LOCK(&create_destruct_mutex);
696 curr_thread = threads;
697 if(curr_thread->tid != 0)
698 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
700 curr_thread = curr_thread->next;
701 if(curr_thread == threads)
703 if(curr_thread->state & PERL_ITHR_DETACHED ||
704 curr_thread->state & PERL_ITHR_JOINED)
706 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
708 MUTEX_UNLOCK(&create_destruct_mutex);
713 ithread_self(char *classname)
716 ST(0) = sv_2mortal(Perl_ithread_self(aTHX_ Nullsv,classname));
721 ithread_tid(ithread *thread)
724 ithread_join(SV *obj)
727 AV* params = Perl_ithread_join(aTHX_ obj);
729 I32 len = AvFILL(params);
730 for (i = 0; i <= len; i++) {
731 SV* tmp = av_shift(params);
735 SvREFCNT_dec(params);
747 ithread_detach(ithread *thread)
750 ithread_DESTROY(SV *thread)
752 #endif /* USE_ITHREADS */
758 PL_perl_destruct_level = 2;
759 MUTEX_INIT(&create_destruct_mutex);
760 MUTEX_LOCK(&create_destruct_mutex);
761 PL_threadhook = &Perl_ithread_hook;
762 thread = (ithread *) PerlMemShared_malloc(sizeof(ithread));
764 PerlLIO_write(PerlIO_fileno(Perl_error_log),
765 PL_no_mem, strlen(PL_no_mem));
768 Zero(thread,1,ithread);
769 PL_perl_destruct_level = 2;
770 MUTEX_INIT(&thread->mutex);
772 thread->next = thread;
773 thread->prev = thread;
774 thread->interp = aTHX;
775 thread->count = 1; /* Immortal. */
776 thread->tid = tid_counter++;
779 thread->state = PERL_ITHR_DETACHED;
781 thread->thr = GetCurrentThreadId();
783 thread->thr = pthread_self();
786 Perl_ithread_set(aTHX_ thread);
787 MUTEX_UNLOCK(&create_destruct_mutex);
788 #endif /* USE_ITHREADS */