This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
new regression tests for bug ID 20010920.007
[perl5.git] / sharedsv.c
index 4359694..d03443c 100644 (file)
 #define PERL_IN_SHAREDSV_C
 #include "perl.h"
 
-PerlInterpreter* sharedsv_space;
-
 #ifdef USE_ITHREADS
 
+
+
 /*
   Shared SV
 
@@ -44,7 +44,8 @@ currently only stores a pointer to the first interpreter.
 void
 Perl_sharedsv_init(pTHX)
 {
-    sharedsv_space = PERL_GET_CONTEXT;
+    PL_sharedsv_space = PERL_GET_CONTEXT;
+    MUTEX_INIT(&PL_sharedsv_space_mutex);
 }
 
 /*
@@ -61,6 +62,8 @@ Perl_sharedsv_new(pTHX)
     New(2555,ssv,1,shared_sv);
     MUTEX_INIT(&ssv->mutex);
     COND_INIT(&ssv->cond);
+    COND_INIT(&ssv->user_cond);
+    ssv->owner = 0;
     ssv->locks = 0;
     return ssv;
 }
@@ -95,15 +98,19 @@ Perl_sharedsv_lock(pTHX_ shared_sv* ssv)
 {
     if(!ssv)
         return;
+    MUTEX_LOCK(&ssv->mutex);
     if(ssv->owner && ssv->owner == my_perl) {
         ssv->locks++;
+       MUTEX_UNLOCK(&ssv->mutex);
         return;
     }
-    MUTEX_LOCK(&ssv->mutex);
+    while(ssv->owner) 
+      COND_WAIT(&ssv->cond,&ssv->mutex);
     ssv->locks++;
     ssv->owner = my_perl;
     if(ssv->locks == 1)
         SAVEDESTRUCTOR_X(Perl_sharedsv_unlock_scope,ssv);
+    MUTEX_UNLOCK(&ssv->mutex);
 }
 
 /*
@@ -117,22 +124,31 @@ Recursively unlocks a shared sv.
 void
 Perl_sharedsv_unlock(pTHX_ shared_sv* ssv)
 {
-    if(ssv->owner != my_perl)
+    MUTEX_LOCK(&ssv->mutex);
+    if(ssv->owner != my_perl) {
+        Perl_croak(aTHX_ "panic: Perl_sharedsv_unlock unlocking mutex that we don't own");
+        MUTEX_UNLOCK(&ssv->mutex); 
         return;
+    } 
 
     if(--ssv->locks == 0) {
         ssv->owner = NULL;
-        MUTEX_UNLOCK(&ssv->mutex);
+       COND_SIGNAL(&ssv->cond);
     }
+    MUTEX_UNLOCK(&ssv->mutex);
  }
 
 void
 Perl_sharedsv_unlock_scope(pTHX_ shared_sv* ssv)
 {
-    if(ssv->owner != my_perl)
+    MUTEX_LOCK(&ssv->mutex);
+    if(ssv->owner != my_perl) {
+        MUTEX_UNLOCK(&ssv->mutex);
         return;
+    }
     ssv->locks = 0;
     ssv->owner = NULL;
+    COND_SIGNAL(&ssv->cond);
     MUTEX_UNLOCK(&ssv->mutex);
 }
 
@@ -145,9 +161,9 @@ Increments the threadcount of a sharedsv.
 void
 Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv)
 {
-  SHAREDSvLOCK(ssv);
+  SHAREDSvEDIT(ssv);
   SvREFCNT_inc(ssv->sv);
-  SHAREDSvUNLOCK(ssv);
+  SHAREDSvRELEASE(ssv);
 }
 
 /*
@@ -163,14 +179,13 @@ void
 Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
 {
     SV* sv;
-    SHAREDSvLOCK(ssv);
     SHAREDSvEDIT(ssv);
     sv = SHAREDSvGET(ssv);
     if (SvREFCNT(sv) == 1) {
         switch (SvTYPE(sv)) {
         case SVt_RV:
             if (SvROK(sv))
-            Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv *)SvIV(SvRV(sv)));
+            Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv *, SvIV(SvRV(sv))));
             break;
         case SVt_PVAV: {
             SV **src_ary  = AvARRAY((AV *)sv);
@@ -178,7 +193,7 @@ Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
 
             while (items-- > 0) {
             if(SvTYPE(*src_ary))
-                Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv *)SvIV(*src_ary++));
+                Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv *, SvIV(*src_ary++)));
             }
             break;
         }
@@ -187,7 +202,7 @@ Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
             (void)hv_iterinit((HV *)sv);
             while ((entry = hv_iternext((HV *)sv)))
                 Perl_sharedsv_thrcnt_dec(
-                    aTHX_ (shared_sv *)SvIV(hv_iterval((HV *)sv, entry))
+                    aTHX_ INT2PTR(shared_sv *, SvIV(hv_iterval((HV *)sv, entry)))
                 );
             break;
         }
@@ -195,7 +210,7 @@ Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
     }
     SvREFCNT_dec(sv);
     SHAREDSvRELEASE(ssv);
-    SHAREDSvUNLOCK(ssv);
 }
 
-#endif
+#endif /* USE_ITHREADS */
+