X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Types.xs;h=cf005cd34fd23c2e14f343950597da42925ef465;hb=569b0505de7c5021759a402e898c1fcaaee2caac;hp=73cacfca18f300e244651da527bd134abe06a57f;hpb=0dcfddc6bb7dd1913079233b16233f4b359162b4;p=perl%2Fmodules%2FLexical-Types.git diff --git a/Types.xs b/Types.xs index 73cacfc..cf005cd 100644 --- a/Types.xs +++ b/Types.xs @@ -45,6 +45,11 @@ /* ... Thread safety and multiplicity ...................................... */ +/* Safe unless stated otherwise in Makefile.PL */ +#ifndef LT_FORKSAFE +# define LT_FORKSAFE 1 +#endif + #ifndef LT_MULTIPLICITY # if defined(MULTIPLICITY) || defined(PERL_IMPLICIT_CONTEXT) # define LT_MULTIPLICITY 1 @@ -373,8 +378,18 @@ STATIC SV *lt_hint(pTHX) { STATIC ptable *lt_op_map = NULL; #ifdef USE_ITHREADS + STATIC perl_mutex lt_op_map_mutex; -#endif + +#define LT_LOCK(M) MUTEX_LOCK(M) +#define LT_UNLOCK(M) MUTEX_UNLOCK(M) + +#else /* USE_ITHREADS */ + +#define LT_LOCK(M) +#define LT_UNLOCK(M) + +#endif /* !USE_ITHREADS */ typedef struct { #ifdef MULTIPLICITY @@ -392,9 +407,7 @@ STATIC void lt_map_store(pTHX_ const OP *o, SV *orig_pkg, SV *type_pkg, SV *type #define lt_map_store(O, OP, TP, TM, PP) lt_map_store(aTHX_ (O), (OP), (TP), (TM), (PP)) lt_op_info *oi; -#ifdef USE_ITHREADS - MUTEX_LOCK(<_op_map_mutex); -#endif + LT_LOCK(<_op_map_mutex); if (!(oi = ptable_fetch(lt_op_map, o))) { oi = PerlMemShared_malloc(sizeof *oi); @@ -443,17 +456,13 @@ STATIC void lt_map_store(pTHX_ const OP *o, SV *orig_pkg, SV *type_pkg, SV *type oi->old_pp_padsv = old_pp_padsv; -#ifdef USE_ITHREADS - MUTEX_UNLOCK(<_op_map_mutex); -#endif + LT_UNLOCK(<_op_map_mutex); } STATIC const lt_op_info *lt_map_fetch(const OP *o, lt_op_info *oi) { const lt_op_info *val; -#ifdef USE_ITHREADS - MUTEX_LOCK(<_op_map_mutex); -#endif + LT_LOCK(<_op_map_mutex); val = ptable_fetch(lt_op_map, o); if (val) { @@ -461,24 +470,18 @@ STATIC const lt_op_info *lt_map_fetch(const OP *o, lt_op_info *oi) { val = oi; } -#ifdef USE_ITHREADS - MUTEX_UNLOCK(<_op_map_mutex); -#endif + LT_UNLOCK(<_op_map_mutex); return val; } STATIC void lt_map_delete(pTHX_ const OP *o) { #define lt_map_delete(O) lt_map_delete(aTHX_ (O)) -#ifdef USE_ITHREADS - MUTEX_LOCK(<_op_map_mutex); -#endif + LT_LOCK(<_op_map_mutex); ptable_map_delete(lt_op_map, o); -#ifdef USE_ITHREADS - MUTEX_UNLOCK(<_op_map_mutex); -#endif + LT_UNLOCK(<_op_map_mutex); } /* --- Hooks --------------------------------------------------------------- */ @@ -489,60 +492,56 @@ STATIC OP *lt_pp_padsv(pTHX) { lt_op_info oi; if (lt_map_fetch(PL_op, &oi)) { - PADOFFSET targ = PL_op->op_targ; - SV *sv = PAD_SVl(targ); - - if (sv) { - SV *orig_pkg, *type_pkg, *type_meth; - int items; - dSP; + SV *orig_pkg, *type_pkg, *type_meth; + int items; + dSP; + dTARGET; - ENTER; - SAVETMPS; + ENTER; + SAVETMPS; #ifdef MULTIPLICITY - { - STRLEN op_len = oi.orig_pkg_len, tp_len = oi.type_pkg_len; - char *buf = oi.buf; - orig_pkg = sv_2mortal(newSVpvn(buf, op_len)); - SvREADONLY_on(orig_pkg); - buf += op_len; - type_pkg = sv_2mortal(newSVpvn(buf, tp_len)); - SvREADONLY_on(type_pkg); - buf += tp_len; - type_meth = sv_2mortal(newSVpvn(buf, oi.type_meth_len)); - SvREADONLY_on(type_meth); - } + { + STRLEN op_len = oi.orig_pkg_len, tp_len = oi.type_pkg_len; + char *buf = oi.buf; + orig_pkg = sv_2mortal(newSVpvn(buf, op_len)); + SvREADONLY_on(orig_pkg); + buf += op_len; + type_pkg = sv_2mortal(newSVpvn(buf, tp_len)); + SvREADONLY_on(type_pkg); + buf += tp_len; + type_meth = sv_2mortal(newSVpvn(buf, oi.type_meth_len)); + SvREADONLY_on(type_meth); + } #else /* MULTIPLICITY */ - orig_pkg = oi.orig_pkg; - type_pkg = oi.type_pkg; - type_meth = oi.type_meth; + orig_pkg = oi.orig_pkg; + type_pkg = oi.type_pkg; + type_meth = oi.type_meth; #endif /* !MULTIPLICITY */ - PUSHMARK(SP); - EXTEND(SP, 3); - PUSHs(type_pkg); - PUSHs(sv); - PUSHs(orig_pkg); - PUTBACK; - - items = call_sv(type_meth, G_ARRAY | G_METHOD); - - SPAGAIN; - switch (items) { - case 0: - break; - case 1: - sv_setsv(sv, POPs); - break; - default: - croak("Typed scalar initializer method should return zero or one scalar, but got %d", items); - } - PUTBACK; + PUSHMARK(SP); + EXTEND(SP, 3); + PUSHs(type_pkg); + PUSHTARG; + PUSHs(orig_pkg); + PUTBACK; - FREETMPS; - LEAVE; + items = call_sv(type_meth, G_ARRAY | G_METHOD); + + SPAGAIN; + switch (items) { + case 0: + break; + case 1: + sv_setsv(TARG, POPs); + break; + default: + croak("Typed scalar initializer method should return zero or one scalar, but got %d", items); } + PUTBACK; + + FREETMPS; + LEAVE; return oi.old_pp_padsv(aTHX); } @@ -676,17 +675,13 @@ LT_PEEP_REC_PROTO { switch (o->op_type) { case OP_PADSV: if (o->op_ppaddr != lt_pp_padsv && o->op_private & OPpLVAL_INTRO) { -#ifdef USE_ITHREADS - MUTEX_LOCK(<_op_map_mutex); -#endif + LT_LOCK(<_op_map_mutex); oi = ptable_fetch(lt_op_map, o); if (oi) { oi->old_pp_padsv = o->op_ppaddr; o->op_ppaddr = lt_pp_padsv; } -#ifdef USE_ITHREADS - MUTEX_UNLOCK(<_op_map_mutex); -#endif + LT_UNLOCK(<_op_map_mutex); } break; #if !LT_HAS_RPEEP @@ -843,6 +838,7 @@ BOOT: stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1); newCONSTSUB(stash, "LT_THREADSAFE", newSVuv(LT_THREADSAFE)); + newCONSTSUB(stash, "LT_FORKSAFE", newSVuv(LT_FORKSAFE)); } lt_setup();