Integrate (-ay) win32 branch at its creation to
[p5sagit/p5-mst-13.2.git] / ext / Thread / Thread.xs
index 45b08d1..841b569 100644 (file)
@@ -82,15 +82,17 @@ threadstart(void *arg)
 #else
     Thread thr = (Thread) arg;
     LOGOP myop;
-    dSP;
+    djSP;
     I32 oldmark = TOPMARK;
     I32 oldscope = scopestack_ix;
     I32 retval;
     AV *returnav;
     int i, ret;
     dJMPENV;
+    DEBUG_L(PerlIO_printf(PerlIO_stderr(), "new thread %p waiting to start\n",
+                         thr));
 
-    /* Don't call *anything* requiring dTHR until after pthread_setspecific */
+    /* Don't call *anything* requiring dTHR until after SET_THR() */
     /*
      * Wait until our creator releases us. If we didn't do this, then
      * it would be potentially possible for out thread to carry on and
@@ -129,6 +131,8 @@ threadstart(void *arg)
        goto finishoff;
     }
 
+    CATCH_SET(TRUE);
+
     /* Now duplicate most of perl_call_sv but with a few twists */
     op = (OP*)&myop;
     Zero(op, 1, LOGOP);
@@ -156,13 +160,18 @@ threadstart(void *arg)
     /* removed for debug */
     SvREFCNT_dec(curstack);
 #endif
-    SvREFCNT_dec(cvcache);
+    SvREFCNT_dec(thr->cvcache);
+    SvREFCNT_dec(thr->magicals);
+    SvREFCNT_dec(thr->specific);
+    SvREFCNT_dec(thr->errsv);
+    SvREFCNT_dec(thr->errhv);
     Safefree(markstack);
     Safefree(scopestack);
     Safefree(savestack);
     Safefree(retstack);
     Safefree(cxstack);
     Safefree(tmps_stack);
+    Safefree(ofs);
 
     MUTEX_LOCK(&thr->mutex);
     DEBUG_L(PerlIO_printf(PerlIO_stderr(),
@@ -208,7 +217,6 @@ static SV *
 newthread (SV *startsv, AV *initargs, char *Class)
 {
 #ifdef USE_THREADS
-    dTHR;
     dSP;
     Thread savethread;
     int i;
@@ -219,41 +227,11 @@ newthread (SV *startsv, AV *initargs, char *Class)
 #endif
     
     savethread = thr;
-    sv = newSVpv("", 0);
-    SvGROW(sv, sizeof(struct thread) + 1);
-    SvCUR_set(sv, sizeof(struct thread));
-    thr = (Thread) SvPVX(sv);
-    DEBUG_L(PerlIO_printf(PerlIO_stderr(), "%p: newthread(%s) = %p)\n",
-                         savethread, SvPEEK(startsv), thr));
-    oursv = sv; 
-    /* If we don't zero these foostack pointers, init_stacks won't init them */
-    markstack = 0;
-    scopestack = 0;
-    savestack = 0;
-    retstack = 0;
-    init_stacks(ARGS);
-    curcop = savethread->Tcurcop;      /* XXX As good a guess as any? */
+    thr = new_struct_thread(thr);
     SPAGAIN;
-    defstash = savethread->Tdefstash;  /* XXX maybe these should */
-    curstash = savethread->Tcurstash;  /* always be set to main? */
-    /* top_env? */
-    /* runlevel */
-    cvcache = newHV();
-    thr->flags = THRf_R_JOINABLE;
-    MUTEX_INIT(&thr->mutex);
-    thr->tid = ++threadnum;
-    /* Insert new thread into the circular linked list and bump nthreads */
-    MUTEX_LOCK(&threads_mutex);
-    thr->next = savethread->next;
-    thr->prev = savethread;
-    savethread->next = thr;
-    thr->next->prev = thr;
-    nthreads++;
-    MUTEX_UNLOCK(&threads_mutex);
-
     DEBUG_L(PerlIO_printf(PerlIO_stderr(),
-                         "%p: newthread, tid is %u, preparing stack\n",
-                         savethread, thr->tid));
+                         "%p: newthread (%p), tid is %u, preparing stack\n",
+                         savethread, thr, thr->tid));
     /* The following pushes the arg list and startsv onto the *new* stack */
     PUSHMARK(sp);
     /* Could easily speed up the following greatly */
@@ -261,7 +239,6 @@ newthread (SV *startsv, AV *initargs, char *Class)
        XPUSHs(SvREFCNT_inc(*av_fetch(initargs, i, FALSE)));
     XPUSHs(SvREFCNT_inc(startsv));
     PUTBACK;
-
 #ifdef THREAD_CREATE
     err = THREAD_CREATE(thr, threadstart);
 #else    
@@ -277,8 +254,10 @@ newthread (SV *startsv, AV *initargs, char *Class)
     MUTEX_UNLOCK(&thr->mutex);
 #endif
     if (err) {
+        DEBUG_L(PerlIO_printf(PerlIO_stderr(),
+                         "%p: create of %p failed %d\n", savethread, thr, err));
        /* Thread creation failed--clean up */
-       SvREFCNT_dec(cvcache);
+       SvREFCNT_dec(thr->cvcache);
        remove_thread(thr);
        MUTEX_DESTROY(&thr->mutex);
        for (i = 0; i <= AvFILL(initargs); i++)
@@ -293,7 +272,7 @@ newthread (SV *startsv, AV *initargs, char *Class)
        croak("panic: sigprocmask");
 #endif
     sv = newSViv(thr->tid);
-    sv_magic(sv, oursv, '~', 0, 0);
+    sv_magic(sv, thr->oursv, '~', 0, 0);
     SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
     return sv_bless(newRV_noinc(sv), gv_stashpv(Class, TRUE));
 #else
@@ -312,6 +291,7 @@ handle_thread_signal(int sig)
 }
 
 MODULE = Thread                PACKAGE = Thread
+PROTOTYPES: DISABLE
 
 void
 new(Class, startsv, ...)
@@ -406,7 +386,7 @@ self(Class)
     PPCODE:        
 #ifdef USE_THREADS
        sv = newSViv(thr->tid);
-       sv_magic(sv, oursv, '~', 0, 0);
+       sv_magic(sv, thr->oursv, '~', 0, 0);
        SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
        PUSHs(sv_2mortal(sv_bless(newRV_noinc(sv), gv_stashpv(Class, TRUE))));
 #endif
@@ -549,7 +529,7 @@ list(Class)
        do {
            SV *sv = (SV*)SvRV(*svp);
            sv_setiv(sv, t->tid);
-           SvMAGIC(sv)->mg_obj = SvREFCNT_inc(t->Toursv);
+           SvMAGIC(sv)->mg_obj = SvREFCNT_inc(t->oursv);
            SvMAGIC(sv)->mg_flags |= MGf_REFCOUNTED;
            SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
            t = t->next;
@@ -599,3 +579,4 @@ await_signal()
        RETVAL = c ? psig_ptr[c] : &sv_no;
     OUTPUT:
        RETVAL
+