threads::shared 1.18
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.xs
index eb96414..cb461cc 100755 (executable)
@@ -12,7 +12,7 @@
 #ifdef HAS_PPPORT_H
 #  define NEED_PL_signals
 #  define NEED_newRV_noinc
-#  define NEED_sv_2pv_nolen
+#  define NEED_sv_2pv_flags
 #  include "ppport.h"
 #  include "threads.h"
 #endif
@@ -452,7 +452,7 @@ S_ithread_run(void * arg)
         SPAGAIN;
         for (ii=len-1; ii >= 0; ii--) {
             SV *sv = POPs;
-            if (jmp_rc == 0) {
+            if (jmp_rc == 0 && (thread->gimme & G_WANT) != G_VOID) {
                 av_store(params, ii, SvREFCNT_inc(sv));
             }
         }
@@ -637,7 +637,7 @@ S_ithread_create(
      * 1 ref to be the responsibility of join/detach, so we don't get
      *      freed until join/detach, even if no thread objects remain.
      *      This allows the following to work:
-     *          { threads->new(sub{...}); } threads->object(1)->join;
+     *          { threads->create(sub{...}); } threads->object(1)->join;
      */
     thread->count = 3;
 
@@ -688,10 +688,8 @@ S_ithread_create(
             thread->init_function = newSV(0);
             sv_copypv(thread->init_function, init_function);
         } else {
-            thread->init_function = sv_dup(init_function, &clone_param);
-            if (SvREFCNT(thread->init_function) == 0) {
-                SvREFCNT_inc_void(thread->init_function);
-            }
+            thread->init_function =
+               SvREFCNT_inc(sv_dup(init_function, &clone_param));
         }
 
         thread->params = sv_dup(params, &clone_param);
@@ -848,7 +846,7 @@ ithread_create(...)
     CODE:
         if ((items >= 2) && SvROK(ST(1)) && SvTYPE(SvRV(ST(1)))==SVt_PVHV) {
             if (--items < 2) {
-                Perl_croak(aTHX_ "Usage: threads->create(\\%specs, function, ...)");
+                Perl_croak(aTHX_ "Usage: threads->create(\\%%specs, function, ...)");
             }
             specs = (HV*)SvRV(ST(1));
             idx = 1;
@@ -896,6 +894,8 @@ ithread_create(...)
                 switch (*str) {
                     case 'a':
                     case 'A':
+                    case 'l':
+                    case 'L':
                         context = G_ARRAY;
                         break;
                     case 's':
@@ -913,6 +913,10 @@ ithread_create(...)
                 if (SvTRUE(*hv_fetch(specs, "array", 5, 0))) {
                     context = G_ARRAY;
                 }
+            } else if (hv_exists(specs, "list", 4)) {
+                if (SvTRUE(*hv_fetch(specs, "list", 4, 0))) {
+                    context = G_ARRAY;
+                }
             } else if (hv_exists(specs, "scalar", 6)) {
                 if (SvTRUE(*hv_fetch(specs, "scalar", 6, 0))) {
                     context = G_SCALAR;
@@ -1067,9 +1071,7 @@ ithread_join(...)
         AV *params = NULL;
         int len;
         int ii;
-#ifdef WIN32
-        DWORD waitcode;
-#else
+#ifndef WIN32
         int rc_join;
         void *retval;
 #endif
@@ -1120,7 +1122,7 @@ ithread_join(...)
         MUTEX_LOCK(&thread->mutex);
         /* Get the return value from the call_sv */
         /* Objects do not survive this process - FIXME */
-        if (! (thread->gimme & G_VOID)) {
+        if ((thread->gimme & G_WANT) != G_VOID) {
             AV *params_copy;
             PerlInterpreter *other_perl;
             CLONE_PARAMS clone_params;
@@ -1457,9 +1459,9 @@ ithread_wantarray(...)
     CODE:
         PERL_UNUSED_VAR(items);
         thread = S_SV_to_ithread(aTHX_ ST(0));
-        ST(0) = (thread->gimme & G_ARRAY) ? &PL_sv_yes :
-                (thread->gimme & G_VOID)  ? &PL_sv_undef
-                           /* G_SCALAR */ : &PL_sv_no;
+        ST(0) = ((thread->gimme & G_WANT) == G_ARRAY) ? &PL_sv_yes :
+                ((thread->gimme & G_WANT) == G_VOID)  ? &PL_sv_undef
+                                       /* G_SCALAR */ : &PL_sv_no;
         /* XSRETURN(1); - implied */