From: Vincent Pit Date: Sat, 7 Mar 2009 00:58:42 +0000 (+0100) Subject: Protect the access to lt_op_map by a mutex X-Git-Tag: v0.04~8 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FLexical-Types.git;a=commitdiff_plain;h=3a70868e5fd2c419e5c78329107019375efc5558 Protect the access to lt_op_map by a mutex --- diff --git a/Types.xs b/Types.xs index a6df2b9..0b5b3f5 100644 --- a/Types.xs +++ b/Types.xs @@ -67,6 +67,10 @@ STATIC SV *lt_hint(pTHX) { STATIC ptable *lt_op_map = NULL; +#ifdef USE_ITHREADS +STATIC perl_mutex lt_op_map_mutex; +#endif + typedef struct { SV *orig_pkg; SV *type_pkg; @@ -75,9 +79,13 @@ typedef struct { } lt_op_info; STATIC void lt_map_store(const OP *o, SV *orig_pkg, SV *type_pkg, SV *type_meth, OP *(*pp_padsv)(pTHX)) { - lt_op_info *oi = ptable_fetch(lt_op_map, o); + lt_op_info *oi; + +#ifdef USE_ITHREADS + MUTEX_LOCK(<_op_map_mutex); +#endif - if (!oi) { + if (!(oi = ptable_fetch(lt_op_map, o))) { oi = PerlMemShared_malloc(sizeof *oi); ptable_store(lt_op_map, o, oi); } @@ -86,14 +94,30 @@ STATIC void lt_map_store(const OP *o, SV *orig_pkg, SV *type_pkg, SV *type_meth, oi->type_pkg = type_pkg; oi->type_meth = type_meth; oi->pp_padsv = pp_padsv; + +#ifdef USE_ITHREADS + MUTEX_UNLOCK(<_op_map_mutex); +#endif } -STATIC const lt_op_info *lt_map_fetch(const OP *o) { - const lt_op_info *oi; +STATIC const lt_op_info *lt_map_fetch(const OP *o, lt_op_info *oi) { + const lt_op_info *val; - oi = ptable_fetch(lt_op_map, o); +#ifdef USE_ITHREADS + MUTEX_LOCK(<_op_map_mutex); +#endif + + val = ptable_fetch(lt_op_map, o); + if (val) { + *oi = *val; + val = oi; + } - return oi; +#ifdef USE_ITHREADS + MUTEX_UNLOCK(<_op_map_mutex); +#endif + + return val; } /* --- Hooks --------------------------------------------------------------- */ @@ -101,9 +125,9 @@ STATIC const lt_op_info *lt_map_fetch(const OP *o) { /* ... Our pp_padsv ........................................................ */ STATIC OP *lt_pp_padsv(pTHX) { - const lt_op_info *oi; + lt_op_info oi; - if ((PL_op->op_private & OPpLVAL_INTRO) && (oi = lt_map_fetch(PL_op))) { + if ((PL_op->op_private & OPpLVAL_INTRO) && lt_map_fetch(PL_op, &oi)) { PADOFFSET targ = PL_op->op_targ; SV *sv = PAD_SVl(targ); @@ -116,12 +140,12 @@ STATIC OP *lt_pp_padsv(pTHX) { PUSHMARK(SP); EXTEND(SP, 3); - PUSHs(oi->type_pkg); + PUSHs(oi.type_pkg); PUSHs(sv); - PUSHs(oi->orig_pkg); + PUSHs(oi.orig_pkg); PUTBACK; - items = call_sv(oi->type_meth, G_ARRAY | G_METHOD); + items = call_sv(oi.type_meth, G_ARRAY | G_METHOD); SPAGAIN; switch (items) { @@ -139,7 +163,7 @@ STATIC OP *lt_pp_padsv(pTHX) { LEAVE; } - return CALL_FPTR(oi->pp_padsv)(aTHX); + return CALL_FPTR(oi.pp_padsv)(aTHX); } return CALL_FPTR(PL_ppaddr[OP_PADSV])(aTHX); @@ -279,6 +303,9 @@ BOOT: { if (!lt_initialized++) { lt_op_map = ptable_new(); +#ifdef USE_ITHREADS + MUTEX_INIT(<_op_map_mutex); +#endif lt_default_meth = newSVpvn("TYPEDSCALAR", 11); SvREADONLY_on(lt_default_meth);