Add test numbers to make "make test" happy. Order is irrelevant
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.xs
index db76082..835cd63 100755 (executable)
@@ -76,6 +76,7 @@ ithread *threads;
 #define ithread_CLONE(thread)          Perl_ithread_CLONE(aTHX_ thread)
 #define ithread_detach(thread)         Perl_ithread_detach(aTHX_ thread)
 #define ithread_tid(thread)            ((thread)->tid)
+#define ithread_yield(thread)          (YIELD);
 
 static perl_mutex create_destruct_mutex;  /* protects the creation and destruction of threads*/
 
@@ -105,8 +106,8 @@ Perl_ithread_destruct (pTHX_ ithread* thread, const char *why)
            threads = NULL;
         }
        else {
-           thread->next->prev = thread->prev->next;
-           thread->prev->next = thread->next->prev;
+           thread->next->prev = thread->prev;
+           thread->prev->next = thread->next;
            if (threads == thread) {
                threads = thread->next;
            }
@@ -122,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
@@ -185,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);
@@ -285,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);
@@ -349,6 +358,7 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
        Zero(thread,1,ithread);
        thread->next = threads;
        thread->prev = threads->prev;
+       threads->prev = thread;
        thread->prev->next = thread;
        /* Set count to 1 immediately in case thread exits before
         * we return to caller !
@@ -393,6 +403,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);
@@ -431,6 +442,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);
 }
 
@@ -504,8 +516,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;
@@ -535,7 +545,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)));
@@ -561,11 +571,15 @@ 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);
 }
 
+void
+ithread_yield(ithread *thread)
 
 void
 ithread_detach(ithread *thread)