More compiler tweaks.
[p5sagit/p5-mst-13.2.git] / ext / Thread / Thread.xs
index ba256c9..3b49dbe 100644 (file)
 #endif
 #include <fcntl.h>
                         
-static U32 threadnum = 0;
 static int sig_pipe[2];
             
 #ifndef THREAD_RET_TYPE
-typedef struct thread *Thread;
 #define THREAD_RET_TYPE void *
 #define THREAD_RET_CAST(x) ((THREAD_RET_TYPE) x)
 #endif
 
 static void
-remove_thread(struct thread *t)
+remove_thread(struct perl_thread *t)
 {
 #ifdef USE_THREADS
     DEBUG_L(WITH_THR(PerlIO_printf(PerlIO_stderr(),
@@ -106,8 +104,8 @@ threadstart(void *arg)
 
     /*
      * It's safe to wait until now to set the thread-specific pointer
-     * from our pthread_t structure to our struct thread, since we're
-     * the only thread who can get at it anyway.
+     * from our pthread_t structure to our struct perl_thread, since
+     * we're the only thread who can get at it anyway.
      */
     SET_THR(thr);
 
@@ -115,44 +113,9 @@ threadstart(void *arg)
     DEBUG_L(PerlIO_printf(PerlIO_stderr(), "new thread %p starting at %s\n",
                          thr, SvPEEK(TOPs)));
 
-#ifdef OLD_WAY
-    JMPENV_PUSH(ret);
-    switch (ret) {
-    case 3:
-        PerlIO_printf(PerlIO_stderr(), "panic: threadstart\n");
-       /* fall through */
-    case 1:
-       STATUS_ALL_FAILURE;
-       /* fall through */
-    case 2:
-       /* my_exit() was called */
-       while (scopestack_ix > oldscope)
-           LEAVE;
-       JMPENV_POP;
-       MUTEX_LOCK(&thr->mutex);
-       thr->flags |= THRf_DID_DIE;
-       MUTEX_UNLOCK(&thr->mutex);
-       av = newSVpvf("Thread called exit with value %d", statusvalue);
-       goto finishoff;
-    }
-
-    CATCH_SET(TRUE);
-
-    /* Now duplicate most of perl_call_sv but with a few twists */
-    op = (OP*)&myop;
-    Zero(op, 1, LOGOP);
-    myop.op_flags = OPf_STACKED;
-    myop.op_next = Nullop;
-    myop.op_flags |= OPf_KNOW;
-    myop.op_flags |= OPf_WANT_LIST;
-    op = pp_entersub(ARGS);
-    if (op)
-       runops();
-#else
     sv = POPs;
     PUTBACK;
     perl_call_sv(sv, G_ARRAY|G_EVAL);
-#endif
     SPAGAIN;
     retval = sp - (stack_base + oldmark);
     sp = stack_base + oldmark + 1;
@@ -163,12 +126,12 @@ threadstart(void *arg)
        av_store(av, 0, &sv_no);
        av_store(av, 1, newSVsv(thr->errsv));
        DEBUG_L(PerlIO_printf(PerlIO_stderr(), "%p died: %s\n",
-                             SvPV(thr->errsv, na));
+                             SvPV(thr->errsv, na)));
     } else {
        DEBUG_L(STMT_START {
            for (i = 1; i <= retval; i++) {
                PerlIO_printf(PerlIO_stderr(), "%p return[%d] = %s\n",
-                               thr, i, SvPEEK(sp[i - 1]));)
+                               thr, i, SvPEEK(sp[i - 1]));
            }
        } STMT_END);
        av_store(av, 0, &sv_yes);
@@ -182,7 +145,7 @@ threadstart(void *arg)
     SvREFCNT_dec(curstack);
 #endif
     SvREFCNT_dec(thr->cvcache);
-    SvREFCNT_dec(thr->magicals);
+    SvREFCNT_dec(thr->threadsv);
     SvREFCNT_dec(thr->specific);
     SvREFCNT_dec(thr->errsv);
     SvREFCNT_dec(thr->errhv);
@@ -244,6 +207,8 @@ newthread (SV *startsv, AV *initargs, char *classname)
     SV *sv;
     int err;
 #ifndef THREAD_CREATE
+    static pthread_attr_t attr;
+    static int attr_inited = 0;
     sigset_t fullmask, oldmask;
 #endif
     
@@ -269,14 +234,22 @@ newthread (SV *startsv, AV *initargs, char *classname)
     sigfillset(&fullmask);
     if (sigprocmask(SIG_SETMASK, &fullmask, &oldmask) == -1)
        croak("panic: sigprocmask");
-    err = pthread_create(&thr->self, pthread_attr_default,
-                        threadstart, (void*) thr);
+    err = 0;
+    if (!attr_inited) {
+       attr_inited = 1;
+       err = pthread_attr_init(&attr);
+       if (err == 0)
+           err = pthread_attr_setdetachstate(&attr, ATTR_JOINABLE);
+    }
+    if (err == 0)
+       err = pthread_create(&thr->self, &attr, threadstart, (void*) thr);
     /* Go */
     MUTEX_UNLOCK(&thr->mutex);
 #endif
     if (err) {
         DEBUG_L(PerlIO_printf(PerlIO_stderr(),
-                         "%p: create of %p failed %d\n", savethread, thr, err));
+                             "%p: create of %p failed %d\n",
+                             savethread, thr, err));
        /* Thread creation failed--clean up */
        SvREFCNT_dec(thr->cvcache);
        remove_thread(thr);
@@ -616,8 +589,10 @@ void
 data(classname = "Thread::Specific")
        char *  classname
     PPCODE:
+#ifdef USE_THREADS
        if (AvFILL(thr->specific) == -1) {
            GV *gv = gv_fetchpv("Thread::Specific::FIELDS", TRUE, SVt_PVHV);
            av_store(thr->specific, 0, newRV((SV*)GvHV(gv)));
        }
        XPUSHs(sv_bless(newRV((SV*)thr->specific),gv_stashpv(classname,TRUE)));
+#endif