Removed last traces of autodetach.
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.xs
index 753c837..ff2df9d 100755 (executable)
@@ -123,13 +123,18 @@ Perl_ithread_destruct (pTHX_ ithread* thread, const char *why)
        MUTEX_UNLOCK(&create_destruct_mutex);
        /* Thread is now disowned */
        if (thread->interp) {
+           dTHXa(thread->interp);
            PERL_SET_CONTEXT(thread->interp);
+           SvREFCNT_dec(thread->params);
+           thread->params = Nullsv;
            perl_destruct(thread->interp);
            perl_free(thread->interp);
            thread->interp = NULL;
        }
        PERL_SET_CONTEXT(aTHX);
        MUTEX_UNLOCK(&thread->mutex);
+       MUTEX_DESTROY(&thread->mutex);
+        PerlMemShared_free(thread);
 }
 
 int
@@ -186,11 +191,16 @@ ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
     MUTEX_LOCK(&thread->mutex);
     thread->count--;
     if (thread->count == 0) {
-       if (!(thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED))) {
-           Perl_warn(aTHX_ "Implicit detach");
-       }
-       MUTEX_UNLOCK(&thread->mutex);
-       Perl_ithread_detach(aTHX_ thread);
+       if(thread->state & PERL_ITHR_FINISHED &&
+          (thread->state & PERL_ITHR_DETACHED ||
+           thread->state & PERL_ITHR_JOINED))
+       {
+            MUTEX_UNLOCK(&thread->mutex);
+            Perl_ithread_destruct(aTHX_ thread, "no reference");
+       }
+       else {
+           MUTEX_UNLOCK(&thread->mutex);
+       }    
     }
     else {
        MUTEX_UNLOCK(&thread->mutex);
@@ -286,8 +296,6 @@ Perl_ithread_run(void * arg) {
 
        if (thread->state & PERL_ITHR_DETACHED) {
                MUTEX_UNLOCK(&thread->mutex);
-               SvREFCNT_dec(thread->params);
-               thread->params = Nullsv;
                Perl_ithread_destruct(aTHX_ thread, "detached finish");
        } else {
                MUTEX_UNLOCK(&thread->mutex);
@@ -359,7 +367,6 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
        MUTEX_INIT(&thread->mutex);
        thread->tid = tid_counter++;
        thread->gimme = GIMME_V;
-       thread->state = (thread->gimme == G_VOID) ? 1 : 0;
 
        /* "Clone" our interpreter into the thread's interpreter
         * This gives thread access to "static data" and code.
@@ -395,6 +402,7 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
            SvTEMP_off(thread->init_function);
            ptr_table_free(PL_ptr_table);
            PL_ptr_table = NULL;
+           PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
        }
 
        PERL_SET_CONTEXT(aTHX);
@@ -433,6 +441,7 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
        known_threads++;
        active_threads++;
        MUTEX_UNLOCK(&create_destruct_mutex);
+       sv_2mortal(params);
        return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
 }
 
@@ -506,8 +515,6 @@ Perl_ithread_join(pTHX_ SV *obj)
        /* We have finished with it */
        thread->state |= PERL_ITHR_JOINED;
        MUTEX_UNLOCK(&thread->mutex);
-       sv_unmagic(SvRV(obj),PERL_MAGIC_shared_scalar);
-       Perl_ithread_destruct(aTHX_ thread, "joined");
        return retparam;
     }
     return (AV*)NULL;
@@ -537,7 +544,7 @@ CODE:
     if (items > 2) {
        int i;
        for(i = 2; i < items ; i++) {
-           av_push(params, ST(i));
+           av_push(params, SvREFCNT_inc(ST(i)));
        }
     }
     ST(0) = sv_2mortal(Perl_ithread_create(aTHX_ Nullsv, classname, function_to_call, newRV_noinc((SV*) params)));
@@ -545,6 +552,23 @@ CODE:
 }
 
 void
+ithread_list(char *classname)
+PPCODE:
+{
+  ithread *curr_thread;
+  MUTEX_LOCK(&create_destruct_mutex);
+  curr_thread = threads;
+  while(curr_thread) {
+    PUSHs( ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE));
+    curr_thread = curr_thread->next;
+    if(curr_thread == threads)
+      break;
+  }    
+  MUTEX_UNLOCK(&create_destruct_mutex);
+}
+
+
+void
 ithread_self(char *classname)
 CODE:
 {
@@ -563,7 +587,9 @@ PPCODE:
   int i;
   I32 len = AvFILL(params);
   for (i = 0; i <= len; i++) {
-    XPUSHs(av_shift(params));
+    SV* tmp = av_shift(params);
+    XPUSHs(tmp);
+    sv_2mortal(tmp);
   }
   SvREFCNT_dec(params);
 }