Integrate mainline @ 18:15 CST 31 Oct 1997
[p5sagit/p5-mst-13.2.git] / ext / Thread / Thread.xs
index 24a11df..e6714aa 100644 (file)
@@ -5,13 +5,26 @@
 /* Magic signature for Thread's mg_private is "Th" */ 
 #define Thread_MAGIC_SIGNATURE 0x5468
 
+#ifdef __cplusplus
+#ifdef I_UNISTD
+#include <unistd.h>
+#endif
+#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(t)
-Thread t;
+remove_thread(struct thread *t)
 {
+#ifdef USE_THREADS
     DEBUG_L(WITH_THR(PerlIO_printf(PerlIO_stderr(),
                                   "%p: remove_thread %p\n", thr, t)));
     MUTEX_LOCK(&threads_mutex);
@@ -21,12 +34,13 @@ Thread t;
     t->next->prev = t->prev;
     COND_BROADCAST(&nthreads_cond);
     MUTEX_UNLOCK(&threads_mutex);
+#endif
 }
 
 static THREAD_RET_TYPE
-threadstart(arg)
-void *arg;
+threadstart(void *arg)
 {
+#ifdef USE_THREADS
 #ifdef FAKE_THREADS
     Thread savethread = thr;
     LOGOP myop;
@@ -185,14 +199,15 @@ void *arg;
                                        /* us unless we're detached, in which */
                                        /* case noone sees the value anyway. */
 #endif    
+#else
+    return THREAD_RET_CAST(NULL);
+#endif
 }
 
 static SV *
-newthread(startsv, initargs, class)
-SV *startsv;
-AV *initargs;
-char *class;
+newthread (SV *startsv, AV *initargs, char *Class)
 {
+#ifdef USE_THREADS
     dTHR;
     dSP;
     Thread savethread;
@@ -204,38 +219,9 @@ 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;
+    thr = new_struct_thread(thr);
     init_stacks(ARGS);
-    curcop = savethread->Tcurcop;      /* XXX As good a guess as any? */
     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));
@@ -248,7 +234,7 @@ char *class;
     PUTBACK;
 
 #ifdef THREAD_CREATE
-    THREAD_CREATE(thr, threadstart);
+    err = THREAD_CREATE(thr, threadstart);
 #else    
     /* On your marks... */
     MUTEX_LOCK(&thr->mutex);
@@ -256,7 +242,8 @@ char *class;
     sigfillset(&fullmask);
     if (sigprocmask(SIG_SETMASK, &fullmask, &oldmask) == -1)
        croak("panic: sigprocmask");
-    err = pthread_create(&self, pthread_attr_default, threadstart, (void*) thr);
+    err = pthread_create(&thr->self, pthread_attr_default,
+                        threadstart, (void*) thr);
     /* Go */
     MUTEX_UNLOCK(&thr->mutex);
 #endif
@@ -279,12 +266,17 @@ char *class;
     sv = newSViv(thr->tid);
     sv_magic(sv, oursv, '~', 0, 0);
     SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
-    return sv_bless(newRV_noinc(sv), gv_stashpv(class, TRUE));
+    return sv_bless(newRV_noinc(sv), gv_stashpv(Class, TRUE));
+#else
+    croak("No threads in this perl");
+    return &sv_undef;
+#endif
 }
 
+static Signal_t handle_thread_signal _((int sig));
+
 static Signal_t
-handle_thread_signal(sig)
-int sig;
+handle_thread_signal(int sig)
 {
     char c = (char) sig;
     write(sig_pipe[0], &c, 1);
@@ -293,12 +285,12 @@ int sig;
 MODULE = Thread                PACKAGE = Thread
 
 void
-new(class, startsv, ...)
-       char *          class
+new(Class, startsv, ...)
+       char *          Class
        SV *            startsv
        AV *            av = av_make(items - 2, &ST(2));
     PPCODE:
-       XPUSHs(sv_2mortal(newthread(startsv, av, class)));
+       XPUSHs(sv_2mortal(newthread(startsv, av, Class)));
 
 void
 join(t)
@@ -306,6 +298,7 @@ join(t)
        AV *    av = NO_INIT
        int     i = NO_INIT
     PPCODE:
+#ifdef USE_THREADS
        DEBUG_L(PerlIO_printf(PerlIO_stderr(), "%p: joining %p (state %u)\n",
                              thr, t, ThrSTATE(t)););
        MUTEX_LOCK(&t->mutex);
@@ -330,11 +323,13 @@ join(t)
        /* Could easily speed up the following if necessary */
        for (i = 0; i <= AvFILL(av); i++)
            XPUSHs(sv_2mortal(*av_fetch(av, i, FALSE)));
+#endif
 
 void
 detach(t)
        Thread  t
     CODE:
+#ifdef USE_THREADS
        DEBUG_L(PerlIO_printf(PerlIO_stderr(), "%p: detaching %p (state %u)\n",
                              thr, t, ThrSTATE(t)););
        MUTEX_LOCK(&t->mutex);
@@ -357,6 +352,7 @@ detach(t)
            croak("can't detach thread");
            /* NOTREACHED */
        }
+#endif
 
 void
 equal(t1, t2)
@@ -369,26 +365,34 @@ void
 flags(t)
        Thread  t
     PPCODE:
+#ifdef USE_THREADS
        PUSHs(sv_2mortal(newSViv(t->flags)));
+#endif
 
 void
-self(class)
-       char *  class
+self(Class)
+       char *  Class
     PREINIT:
        SV *sv;
-    PPCODE:
+    PPCODE:        
+#ifdef USE_THREADS
        sv = newSViv(thr->tid);
        sv_magic(sv, oursv, '~', 0, 0);
        SvMAGIC(sv)->mg_private = Thread_MAGIC_SIGNATURE;
-       PUSHs(sv_2mortal(sv_bless(newRV_noinc(sv), gv_stashpv(class, TRUE))));
+       PUSHs(sv_2mortal(sv_bless(newRV_noinc(sv), gv_stashpv(Class, TRUE))));
+#endif
 
 U32
 tid(t)
        Thread  t
     CODE:
+#ifdef USE_THREADS
        MUTEX_LOCK(&t->mutex);
        RETVAL = t->tid;
        MUTEX_UNLOCK(&t->mutex);
+#else 
+       RETVAL = 0;
+#endif
     OUTPUT:
        RETVAL
 
@@ -401,13 +405,18 @@ DESTROY(t)
 void
 yield()
     CODE:
+{
+#ifdef USE_THREADS
        YIELD;
+#endif
+}
 
 void
 cond_wait(sv)
        SV *    sv
        MAGIC * mg = NO_INIT
-CODE:
+CODE:                       
+#ifdef USE_THREADS
        if (SvROK(sv))
            sv = SvRV(sv);
 
@@ -424,12 +433,14 @@ CODE:
            COND_WAIT(MgOWNERCONDP(mg), MgMUTEXP(mg));
        MgOWNER(mg) = thr;
        MUTEX_UNLOCK(MgMUTEXP(mg));
-       
+#endif
+
 void
 cond_signal(sv)
        SV *    sv
        MAGIC * mg = NO_INIT
 CODE:
+#ifdef USE_THREADS
        if (SvROK(sv))
            sv = SvRV(sv);
 
@@ -442,12 +453,14 @@ CODE:
        }
        COND_SIGNAL(MgCONDP(mg));
        MUTEX_UNLOCK(MgMUTEXP(mg));
+#endif
 
 void
 cond_broadcast(sv)
        SV *    sv
        MAGIC * mg = NO_INIT
-CODE:
+CODE: 
+#ifdef USE_THREADS
        if (SvROK(sv))
            sv = SvRV(sv);
 
@@ -461,16 +474,18 @@ CODE:
        }
        COND_BROADCAST(MgCONDP(mg));
        MUTEX_UNLOCK(MgMUTEXP(mg));
+#endif
 
 void
-list(class)
-       char *  class
+list(Class)
+       char *  Class
     PREINIT:
        Thread  t;
        AV *    av;
        SV **   svp;
        int     n = 0;
     PPCODE:
+#ifdef USE_THREADS
        av = newAV();
        /*
         * Iterate until we have enough dynamic storage for all threads.
@@ -486,7 +501,7 @@ list(class)
                    SV *sv = newSViv(0);        /* fill in tid later */
                    sv_magic(sv, 0, '~', 0, 0); /* fill in other magic later */
                    av_push(av, sv_bless(newRV_noinc(sv),
-                                        gv_stashpv(class, TRUE)));
+                                        gv_stashpv(Class, TRUE)));
        
                }
            }
@@ -520,6 +535,7 @@ list(class)
        for (svp = AvARRAY(av); n > 0; n--, svp++)
            PUSHs(*svp);
        (void)sv_2mortal((SV*)av);
+#endif
 
 
 MODULE = Thread                PACKAGE = Thread::Signal