X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sharedsv.c;h=e4b6e0ff36c0961905b751b673a57a050ae740ed;hb=1779d84dfb511a39bc8c645afc698f9dce95ef29;hp=1703257cf21d1d2b1d342986ea27ff9ef0ec0eb9;hpb=667883b043ec7c3a2eb983d65a38f863f9a39fbd;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sharedsv.c b/sharedsv.c index 1703257..e4b6e0f 100644 --- a/sharedsv.c +++ b/sharedsv.c @@ -20,11 +20,10 @@ #define PERL_IN_SHAREDSV_C #include "perl.h" -PerlInterpreter* sharedsv_space; -perl_mutex sharedsv_space_mutex; - #ifdef USE_ITHREADS + + /* Shared SV @@ -45,8 +44,11 @@ currently only stores a pointer to the first interpreter. void Perl_sharedsv_init(pTHX) { - sharedsv_space = PERL_GET_CONTEXT; - MUTEX_INIT(&sharedsv_space_mutex); + PerlInterpreter* old_context = PERL_GET_CONTEXT; + PL_sharedsv_space = perl_alloc(); + perl_construct(PL_sharedsv_space); + PERL_SET_CONTEXT(old_context); + MUTEX_INIT(&PL_sharedsv_space_mutex); } /* @@ -63,7 +65,10 @@ 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; + ssv->index = 0; return ssv; } @@ -80,8 +85,29 @@ looking at magic, or by checking if it is tied again threads::shared. shared_sv * Perl_sharedsv_find(pTHX_ SV* sv) { - /* does all it can to find a shared_sv struct, returns NULL otherwise */ - shared_sv* ssv = NULL; + /* does all it can to find a shared_sv struct, returns NULL otherwise */ + shared_sv* ssv = NULL; + switch (SvTYPE(sv)) { + case SVt_PVMG: + case SVt_PVAV: + case SVt_PVHV: { + MAGIC* mg = mg_find(sv, PERL_MAGIC_ext); + if(mg) { + if(strcmp(mg->mg_ptr,"threads::shared")) + break; + ssv = INT2PTR(shared_sv *, SvIV(mg->mg_obj)); + break; + } + + mg = mg_find(sv,PERL_MAGIC_tied); + if(mg) { + SV* obj = SvTIED_obj(sv,mg); + if(sv_derived_from(obj, "threads::shared")) + ssv = INT2PTR(shared_sv *, SvIV(SvRV(obj))); + break; + } + } + } return ssv; } @@ -89,7 +115,7 @@ Perl_sharedsv_find(pTHX_ SV* sv) =for apidoc sharedsv_lock Recursive locks on a sharedsv. -Locks are dynamicly scoped at the level of the first lock. +Locks are dynamically scoped at the level of the first lock. =cut */ void @@ -97,15 +123,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); } /* @@ -119,22 +149,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); } @@ -147,9 +186,9 @@ Increments the threadcount of a sharedsv. void Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv) { - SHAREDSvEDIT(ssv); + SHAREDSvLOCK(ssv); SvREFCNT_inc(ssv->sv); - SHAREDSvRELEASE(ssv); + SHAREDSvUNLOCK(ssv); } /* @@ -165,13 +204,13 @@ void Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv) { SV* sv; - SHAREDSvEDIT(ssv); + SHAREDSvLOCK(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); @@ -179,7 +218,8 @@ 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))); + src_ary++; } break; } @@ -188,14 +228,15 @@ 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; } } } - SvREFCNT_dec(sv); - SHAREDSvRELEASE(ssv); + Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(ssv)); + SHAREDSvUNLOCK(ssv); } -#endif +#endif /* USE_ITHREADS */ +