X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Findirect.git;a=blobdiff_plain;f=indirect.xs;h=df9bca8d979753c50637b079c8b639cab73f51c8;hp=3f5a8cc7783a7d380dbc6beeb67c54cbe72103a2;hb=fa4e8647e6ef975de34b783d7b8fe2644765a0f8;hpb=40f70c31fb7b062366bd46139b577fa477de4c7a diff --git a/indirect.xs b/indirect.xs index 3f5a8cc..df9bca8 100644 --- a/indirect.xs +++ b/indirect.xs @@ -95,6 +95,11 @@ /* ... Thread safety and multiplicity ...................................... */ +/* Safe unless stated otherwise in Makefile.PL */ +#ifndef I_FORKSAFE +# define I_FORKSAFE 1 +#endif + #ifndef I_MULTIPLICITY # if defined(MULTIPLICITY) || defined(PERL_IMPLICIT_CONTEXT) # define I_MULTIPLICITY 1 @@ -136,8 +141,8 @@ #if I_WORKAROUND_REQUIRE_PROPAGATION typedef struct { - SV *code; - I32 requires; + SV *code; + IV cxreq; } indirect_hint_t; #define I_HINT_STRUCT 1 @@ -251,11 +256,11 @@ STATIC void indirect_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) { #if I_HINT_STRUCT - h2 = PerlMemShared_malloc(sizeof *h2); - h2->code = indirect_clone(h1->code, ud->owner); + h2 = PerlMemShared_malloc(sizeof *h2); + h2->code = indirect_clone(h1->code, ud->owner); SvREFCNT_inc(h2->code); #if I_WORKAROUND_REQUIRE_PROPAGATION - h2->requires = h1->requires; + h2->cxreq = h1->cxreq; #endif #else /* I_HINT_STRUCT */ @@ -288,6 +293,26 @@ STATIC void indirect_thread_cleanup(pTHX_ void *ud) { #endif /* I_THREADSAFE */ +#if I_WORKAROUND_REQUIRE_PROPAGATION +STATIC IV indirect_require_tag(pTHX) { +#define indirect_require_tag() indirect_require_tag(aTHX) + const PERL_SI *si; + + for (si = PL_curstackinfo; si; si = si->si_prev) { + I32 cxix; + + for (cxix = si->si_cxix; cxix >= 0; --cxix) { + const PERL_CONTEXT *cx = si->si_cxstack + cxix; + + if (CxTYPE(cx) == CXt_EVAL && cx->blk_eval.old_op_type == OP_REQUIRE) + return PTR2IV(cx); + } + } + + return PTR2IV(NULL); +} +#endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ + STATIC SV *indirect_tag(pTHX_ SV *value) { #define indirect_tag(V) indirect_tag(aTHX_ (V)) indirect_hint_t *h; @@ -304,28 +329,10 @@ STATIC SV *indirect_tag(pTHX_ SV *value) { #if I_HINT_STRUCT h = PerlMemShared_malloc(sizeof *h); - h->code = code; - -#if I_WORKAROUND_REQUIRE_PROPAGATION - { - const PERL_SI *si; - I32 requires = 0; - - for (si = PL_curstackinfo; si; si = si->si_prev) { - I32 cxix; - - for (cxix = si->si_cxix; cxix >= 0; --cxix) { - const PERL_CONTEXT *cx = si->si_cxstack + cxix; - - if (CxTYPE(cx) == CXt_EVAL && cx->blk_eval.old_op_type == OP_REQUIRE) - ++requires; - } - } - - h->requires = requires; - } -#endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ - + h->code = code; +# if I_WORKAROUND_REQUIRE_PROPAGATION + h->cxreq = indirect_require_tag(); +# endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ #else /* I_HINT_STRUCT */ h = code; #endif /* !I_HINT_STRUCT */ @@ -354,22 +361,8 @@ STATIC SV *indirect_detag(pTHX_ const SV *hint) { #endif /* I_THREADSAFE */ #if I_WORKAROUND_REQUIRE_PROPAGATION - { - const PERL_SI *si; - I32 requires = 0; - - for (si = PL_curstackinfo; si; si = si->si_prev) { - I32 cxix; - - for (cxix = si->si_cxix; cxix >= 0; --cxix) { - const PERL_CONTEXT *cx = si->si_cxstack + cxix; - - if (CxTYPE(cx) == CXt_EVAL && cx->blk_eval.old_op_type == OP_REQUIRE - && ++requires > h->requires) - return NULL; - } - } - } + if (indirect_require_tag() != h->cxreq) + return NULL; #endif /* I_WORKAROUND_REQUIRE_PROPAGATION */ return I_HINT_CODE(h); @@ -857,6 +850,7 @@ BOOT: stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1); newCONSTSUB(stash, "I_THREADSAFE", newSVuv(I_THREADSAFE)); + newCONSTSUB(stash, "I_FORKSAFE", newSVuv(I_FORKSAFE)); } indirect_setup();