1 #define PERL_NO_GET_CONTEXT
8 #include <win32thread.h>
9 #define PERL_THREAD_SETSPECIFIC(k,v) TlsSetValue(k,v)
10 #define PERL_THREAD_GETSPECIFIC(k,v) v = TlsGetValue(k)
11 #define PERL_THREAD_ALLOC_SPECIFIC(k) \
13 if((k = TlsAlloc()) == TLS_OUT_OF_INDEXES) {\
14 PerlIO_printf(PerlIO_stderr(),"panic threads.h: TlsAlloc");\
22 #define PERL_THREAD_SETSPECIFIC(k,v) pthread_setspecific(k,v)
23 #ifdef OLD_PTHREADS_API
24 #define PERL_THREAD_DETACH(t) pthread_detach(&(t))
25 #define PERL_THREAD_GETSPECIFIC(k,v) pthread_getspecific(k,&v)
26 #define PERL_THREAD_ALLOC_SPECIFIC(k) STMT_START {\
27 if(pthread_keycreate(&(k),0)) {\
28 PerlIO_printf(PerlIO_stderr(), "panic threads.h: pthread_key_create");\
33 #define PERL_THREAD_DETACH(t) pthread_detach((t))
34 #define PERL_THREAD_GETSPECIFIC(k,v) v = pthread_getspecific(k)
35 #define PERL_THREAD_ALLOC_SPECIFIC(k) STMT_START {\
36 if(pthread_key_create(&(k),0)) {\
37 PerlIO_printf(PerlIO_stderr(), "panic threads.h: pthread_key_create");\
44 typedef struct ithread_s {
45 struct ithread_s *next; /* next thread in the list */
46 struct ithread_s *prev; /* prev thread in the list */
47 PerlInterpreter *interp; /* The threads interpreter */
48 I32 tid; /* threads module's thread id */
49 perl_mutex mutex; /* mutex for updating things in this struct */
50 I32 count; /* how many SVs have a reference to us */
51 signed char detached; /* are we detached ? */
52 int gimme; /* Context of create */
53 SV* init_function; /* Code to run */
54 SV* params; /* args to pass function */
56 DWORD thr; /* OS's idea if thread id */
57 HANDLE handle; /* OS's waitable handle */
59 pthread_t thr; /* OS's handle for the thread */
65 /* Macros to supply the aTHX_ in an embed.h like manner */
66 #define ithread_join(thread) Perl_ithread_join(aTHX_ thread)
67 #define ithread_DESTROY(thread) Perl_ithread_DESTROY(aTHX_ thread)
68 #define ithread_CLONE(thread) Perl_ithread_CLONE(aTHX_ thread)
69 #define ithread_detach(thread) Perl_ithread_detach(aTHX_ thread)
70 #define ithread_tid(thread) ((thread)->tid)
72 static perl_mutex create_destruct_mutex; /* protects the creation and destruction of threads*/
75 I32 active_threads = 0;
79 * Clear up after thread is done with
82 Perl_ithread_destruct (pTHX_ ithread* thread)
84 MUTEX_LOCK(&thread->mutex);
85 if (thread->count != 0) {
86 MUTEX_UNLOCK(&thread->mutex);
89 MUTEX_LOCK(&create_destruct_mutex);
90 /* Remove from circular list of threads */
91 if (thread->next == thread) {
92 /* last one should never get here ? */
96 thread->next->prev = thread->prev->next;
97 thread->prev->next = thread->next->prev;
98 if (threads == thread) {
99 threads = thread->next;
103 MUTEX_UNLOCK(&create_destruct_mutex);
104 /* Thread is now disowned */
106 Perl_warn(aTHX_ "destruct %d @ %p by %p",
107 thread->tid,thread->interp,aTHX);
109 if (thread->interp) {
110 dTHXa(thread->interp);
111 PERL_SET_CONTEXT(thread->interp);
112 perl_destruct(thread->interp);
113 perl_free(thread->interp);
114 thread->interp = NULL;
116 PERL_SET_CONTEXT(aTHX);
117 MUTEX_UNLOCK(&thread->mutex);
121 /* MAGIC (in mg.h sense) hooks */
124 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
126 ithread *thread = (ithread *) mg->mg_ptr;
127 SvIVX(sv) = PTR2IV(thread);
133 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
135 ithread *thread = (ithread *) mg->mg_ptr;
136 MUTEX_LOCK(&thread->mutex);
138 MUTEX_UNLOCK(&thread->mutex);
139 /* This is safe as it re-checks count */
140 Perl_ithread_destruct(aTHX_ thread);
145 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
147 ithread *thread = (ithread *) mg->mg_ptr;
148 MUTEX_LOCK(&thread->mutex);
150 MUTEX_UNLOCK(&thread->mutex);
154 MGVTBL ithread_vtbl = {
155 ithread_mg_get, /* get */
159 ithread_mg_free, /* free */
161 ithread_mg_dup /* dup */
166 * Starts executing the thread. Needs to clean up memory a tad better.
167 * Passed as the C level function to run in the new thread
172 Perl_ithread_run(LPVOID arg) {
175 Perl_ithread_run(void * arg) {
177 ithread* thread = (ithread*) arg;
178 dTHXa(thread->interp);
179 PERL_SET_CONTEXT(thread->interp);
180 PERL_THREAD_SETSPECIFIC(self_key,thread);
183 /* Far from clear messing with ->thr child-side is a good idea */
184 MUTEX_LOCK(&thread->mutex);
186 thread->thr = GetCurrentThreadId();
188 thread->thr = pthread_self();
190 MUTEX_UNLOCK(&thread->mutex);
193 PL_perl_destruct_level = 2;
196 AV* params = (AV*) SvRV(thread->params);
197 I32 len = av_len(params)+1;
203 for(i = 0; i < len; i++) {
204 XPUSHs(av_shift(params));
207 len = call_sv(thread->init_function, thread->gimme|G_EVAL);
209 for (i=len-1; i >= 0; i--) {
211 av_store(params, i, SvREFCNT_inc(sv));
215 Perl_warn(aTHX_ "Died:%_",ERRSV);
219 SvREFCNT_dec(thread->init_function);
222 PerlIO_flush((PerlIO*)NULL);
223 MUTEX_LOCK(&thread->mutex);
224 if (thread->detached & 1) {
225 MUTEX_UNLOCK(&thread->mutex);
226 SvREFCNT_dec(thread->params);
227 thread->params = Nullsv;
228 Perl_ithread_destruct(aTHX_ thread);
230 thread->detached |= 4;
231 MUTEX_UNLOCK(&thread->mutex);
241 ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
246 MUTEX_LOCK(&thread->mutex);
248 MUTEX_UNLOCK(&thread->mutex);
252 sv = newSVrv(obj,classname);
253 sv_setiv(sv,PTR2IV(thread));
254 mg = sv_magicext(sv,Nullsv,PERL_MAGIC_shared_scalar,&ithread_vtbl,(char *)thread,0);
255 mg->mg_flags |= MGf_DUP;
261 SV_to_ithread(pTHX_ SV *sv)
266 thread = INT2PTR(ithread*, SvIV(SvRV(sv)));
270 PERL_THREAD_GETSPECIFIC(self_key,thread);
276 * iThread->create(); ( aka iThread->new() )
277 * Called in context of parent thread
281 Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* params)
284 CLONE_PARAMS clone_param;
286 MUTEX_LOCK(&create_destruct_mutex);
287 thread = PerlMemShared_malloc(sizeof(ithread));
288 Zero(thread,1,ithread);
289 thread->next = threads;
290 thread->prev = threads->prev;
291 thread->prev->next = thread;
292 /* Set count to 1 immediately in case thread exits before
293 * we return to caller !
296 MUTEX_INIT(&thread->mutex);
297 thread->tid = tid_counter++;
298 thread->gimme = GIMME_V;
299 thread->detached = (thread->gimme == G_VOID) ? 1 : 0;
301 /* "Clone" our interpreter into the thread's interpreter
302 * This gives thread access to "static data" and code.
305 PerlIO_flush((PerlIO*)NULL);
308 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
310 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
312 /* perl_clone leaves us in new interpreter's context.
313 As it is tricky to spot implcit aTHX create a new scope
314 with aTHX matching the context for the duration of
315 our work for new interpreter.
318 dTHXa(thread->interp);
319 /* Here we remove END blocks since they should only run
320 in the thread they are created
322 SvREFCNT_dec(PL_endav);
324 clone_param.flags = 0;
325 thread->init_function = sv_dup(init_function, &clone_param);
326 if (SvREFCNT(thread->init_function) == 0) {
327 SvREFCNT_inc(thread->init_function);
330 thread->params = sv_dup(params, &clone_param);
331 SvREFCNT_inc(thread->params);
332 SvTEMP_off(thread->init_function);
333 ptr_table_free(PL_ptr_table);
337 PERL_SET_CONTEXT(aTHX);
339 /* Start the thread */
343 thread->handle = CreateThread(NULL, 0, Perl_ithread_run,
344 (LPVOID)thread, 0, &thread->thr);
348 static pthread_attr_t attr;
349 static int attr_inited = 0;
350 sigset_t fullmask, oldmask;
351 static int attr_joinable = PTHREAD_CREATE_JOINABLE;
354 pthread_attr_init(&attr);
356 # ifdef PTHREAD_ATTR_SETDETACHSTATE
357 PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
359 # ifdef THREAD_CREATE_NEEDS_STACK
360 if(pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK))
361 croak("panic: pthread_attr_setstacksize failed");
364 #ifdef OLD_PTHREADS_API
365 pthread_create( &thread->thr, attr, Perl_ithread_run, (void *)thread);
367 pthread_create( &thread->thr, &attr, Perl_ithread_run, (void *)thread);
372 MUTEX_UNLOCK(&create_destruct_mutex);
373 return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
377 Perl_ithread_self (pTHX_ SV *obj, char* Class)
380 PERL_THREAD_GETSPECIFIC(self_key,thread);
381 return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
385 * Joins the thread this code needs to take the returnvalue from the
386 * call_sv and send it back
390 Perl_ithread_CLONE(pTHX_ SV *obj)
394 ithread *thread = SV_to_ithread(aTHX_ obj);
398 Perl_warn(aTHX_ "CLONE %_",obj);
403 Perl_ithread_join(pTHX_ SV *obj)
405 ithread *thread = SV_to_ithread(aTHX_ obj);
406 MUTEX_LOCK(&thread->mutex);
407 if (thread->detached & 1) {
408 MUTEX_UNLOCK(&thread->mutex);
409 Perl_croak(aTHX_ "Cannot join a detached thread");
411 else if (thread->detached & 2) {
412 MUTEX_UNLOCK(&thread->mutex);
413 Perl_croak(aTHX_ "Thread already joined");
422 MUTEX_UNLOCK(&thread->mutex);
424 waitcode = WaitForSingleObject(thread->handle, INFINITE);
426 pthread_join(thread->thr,&retval);
428 MUTEX_LOCK(&thread->mutex);
431 AV* params = (AV*) SvRV(thread->params);
432 CLONE_PARAMS clone_params;
433 clone_params.stashes = newAV();
434 PL_ptr_table = ptr_table_new();
435 retparam = (AV*) sv_dup((SV*)params, &clone_params);
436 SvREFCNT_dec(clone_params.stashes);
437 SvREFCNT_inc(retparam);
438 ptr_table_free(PL_ptr_table);
442 /* sv_dup over the args */
443 /* We have finished with it */
444 thread->detached |= 2;
445 MUTEX_UNLOCK(&thread->mutex);
446 sv_unmagic(SvRV(obj),PERL_MAGIC_shared_scalar);
447 Perl_ithread_destruct(aTHX_ thread);
454 Perl_ithread_detach(pTHX_ ithread *thread)
456 MUTEX_LOCK(&thread->mutex);
457 if (!thread->detached) {
458 thread->detached = 1;
460 CloseHandle(thread->handle);
463 PERL_THREAD_DETACH(thread->thr);
466 MUTEX_UNLOCK(&thread->mutex);
471 Perl_ithread_DESTROY(pTHX_ SV *sv)
473 ithread *thread = SV_to_ithread(aTHX_ sv);
474 sv_unmagic(SvRV(sv),PERL_MAGIC_shared_scalar);
479 MODULE = threads PACKAGE = threads PREFIX = ithread_
483 ithread_new (classname, function_to_call, ...)
485 SV * function_to_call
488 AV* params = newAV();
491 for(i = 2; i < items ; i++) {
492 av_push(params, ST(i));
495 ST(0) = sv_2mortal(Perl_ithread_create(aTHX_ Nullsv, classname, function_to_call, newRV_noinc((SV*) params)));
500 ithread_self(char *classname)
503 ST(0) = sv_2mortal(Perl_ithread_self(aTHX_ Nullsv,classname));
508 ithread_tid(ithread *thread)
511 ithread_join(SV *obj)
514 AV* params = Perl_ithread_join(aTHX_ obj);
516 I32 len = AvFILL(params);
517 for (i = 0; i <= len; i++) {
518 XPUSHs(av_shift(params));
520 SvREFCNT_dec(params);
525 ithread_detach(ithread *thread)
528 ithread_DESTROY(SV *thread)
533 PL_perl_destruct_level = 2;
534 PERL_THREAD_ALLOC_SPECIFIC(self_key);
535 MUTEX_INIT(&create_destruct_mutex);
536 MUTEX_LOCK(&create_destruct_mutex);
537 thread = PerlMemShared_malloc(sizeof(ithread));
538 Zero(thread,1,ithread);
539 PL_perl_destruct_level = 2;
540 MUTEX_INIT(&thread->mutex);
542 thread->next = thread;
543 thread->prev = thread;
544 thread->interp = aTHX;
545 thread->count = 1; /* imortal */
546 thread->tid = tid_counter++;
548 thread->detached = 1;
550 thread->thr = GetCurrentThreadId();
552 thread->thr = pthread_self();
554 PERL_THREAD_SETSPECIFIC(self_key,thread);
555 MUTEX_UNLOCK(&create_destruct_mutex);