perl_mutex mutex; /* mutex for updating things in this struct */
I32 count; /* how many SVs have a reference to us */
signed char detached; /* are we detached ? */
+ int gimme; /* Context of create */
SV* init_function; /* Code to run */
SV* params; /* args to pass function */
#ifdef WIN32
Perl_ithread_destruct (pTHX_ ithread* thread)
{
MUTEX_LOCK(&thread->mutex);
- Perl_warn(aTHX_ "destruct %d with count=%d",thread->tid,thread->count);
if (thread->count != 0) {
MUTEX_UNLOCK(&thread->mutex);
return;
}
MUTEX_UNLOCK(&create_mutex);
/* Thread is now disowned */
+#if 0
+ Perl_warn(aTHX_ "destruct %d @ %p by %p",
+ thread->tid,thread->interp,aTHX);
+#endif
if (thread->interp) {
dTHXa(thread->interp);
PERL_SET_CONTEXT(thread->interp);
{
ithread *thread = (ithread *) mg->mg_ptr;
MUTEX_LOCK(&thread->mutex);
- Perl_warn(aTHX_ "Unmagic %d with count=%d",thread->tid,thread->count);
thread->count--;
MUTEX_UNLOCK(&thread->mutex);
/* This is safe as it re-checks count */
{
ithread *thread = (ithread *) mg->mg_ptr;
MUTEX_LOCK(&thread->mutex);
- Perl_warn(aTHX_ "DUP %d with count=%d",thread->tid,thread->count);
thread->count++;
MUTEX_UNLOCK(&thread->mutex);
return 0;
XPUSHs(av_shift(params));
}
PUTBACK;
- call_sv(thread->init_function, G_DISCARD|G_EVAL);
+ len = call_sv(thread->init_function, thread->gimme|G_EVAL);
SPAGAIN;
+ for (i=len-1; i >= 0; i--) {
+ SV *sv = POPs;
+ av_store(params, i, SvREFCNT_inc(sv));
+ }
+ PUTBACK;
+ if (SvTRUE(ERRSV)) {
+ Perl_warn(aTHX_ "Died:%_",ERRSV);
+ }
FREETMPS;
LEAVE;
- SvREFCNT_dec(thread->params);
SvREFCNT_dec(thread->init_function);
}
PerlIO_flush((PerlIO*)NULL);
MUTEX_LOCK(&thread->mutex);
- Perl_warn(aTHX_ "finished %d with count=%d",thread->tid,thread->count);
- if (thread->detached == 1) {
+ if (thread->detached & 1) {
MUTEX_UNLOCK(&thread->mutex);
+ SvREFCNT_dec(thread->params);
+ thread->params = Nullsv;
Perl_ithread_destruct(aTHX_ thread);
} else {
+ thread->detached |= 4;
MUTEX_UNLOCK(&thread->mutex);
}
#ifdef WIN32
if (inc) {
MUTEX_LOCK(&thread->mutex);
thread->count++;
- Perl_warn(aTHX_ "SV for %d with count=%d",thread->tid,thread->count);
MUTEX_UNLOCK(&thread->mutex);
}
if (!obj)
thread->count = 1;
MUTEX_INIT(&thread->mutex);
thread->tid = tid_counter++;
- thread->detached = 0;
+ thread->gimme = GIMME_V;
+ thread->detached = (thread->gimme == G_VOID) ? 1 : 0;
/* "Clone" our interpreter into the thread's interpreter
* This gives thread access to "static data" and code.
#else
thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
#endif
+ /* perl_clone leaves us in new interpreter's context.
+ As it is tricky to spot implcit aTHX create a new scope
+ with aTHX matching the context for the duration of
+ our work for new interpreter.
+ */
+ {
+ dTHXa(thread->interp);
- clone_param.flags = 0;
- thread->init_function = Perl_sv_dup(thread->interp, init_function, &clone_param);
- if (SvREFCNT(thread->init_function) == 0) {
- SvREFCNT_inc(thread->init_function);
- }
-
- thread->params = Perl_sv_dup(thread->interp,params, &clone_param);
- SvREFCNT_inc(thread->params);
- SvTEMP_off(thread->init_function);
- ptr_table_free(PL_ptr_table);
- PL_ptr_table = NULL;
+ clone_param.flags = 0;
+ thread->init_function = sv_dup(init_function, &clone_param);
+ if (SvREFCNT(thread->init_function) == 0) {
+ SvREFCNT_inc(thread->init_function);
+ }
+
+ thread->params = sv_dup(params, &clone_param);
+ SvREFCNT_inc(thread->params);
+ SvTEMP_off(thread->init_function);
+ ptr_table_free(PL_ptr_table);
+ PL_ptr_table = NULL;
+ }
PERL_SET_CONTEXT(aTHX);
{
ithread *thread = SV_to_ithread(aTHX_ obj);
MUTEX_LOCK(&thread->mutex);
- Perl_warn(aTHX_ "joining %d with count=%d",thread->tid,thread->count);
- if (!thread->detached) {
+ if (thread->detached & 1) {
+ MUTEX_UNLOCK(&thread->mutex);
+ Perl_croak(aTHX_ "Cannot join a detached thread");
+ }
+ else if (thread->detached & 2) {
+ MUTEX_UNLOCK(&thread->mutex);
+ Perl_croak(aTHX_ "Thread already joined");
+ }
+ else {
#ifdef WIN32
DWORD waitcode;
#else
#else
pthread_join(thread->thr,&retval);
#endif
- Perl_warn(aTHX_ "joined %d with count=%d",thread->tid,thread->count);
- /* We have finished with it */
MUTEX_LOCK(&thread->mutex);
- thread->detached = 2;
+ /* sv_dup over the args */
+ /* We have finished with it */
+ thread->detached |= 2;
MUTEX_UNLOCK(&thread->mutex);
sv_unmagic(SvRV(obj),PERL_MAGIC_shared_scalar);
}
- else {
- MUTEX_UNLOCK(&thread->mutex);
- Perl_croak(aTHX_ "Cannot join a detached thread");
- }
}
void
Perl_ithread_DESTROY(pTHX_ SV *sv)
{
ithread *thread = SV_to_ithread(aTHX_ sv);
- Perl_warn(aTHX_ "DESTROY %d with count=%d",thread->tid,thread->count);
sv_unmagic(SvRV(sv),PERL_MAGIC_shared_scalar);
}
void
ithread_DESTROY(SV *thread)
-void
-ithread_CLONE(SV *sv)
-
BOOT:
{
ithread* thread;