X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Hooks.xs;h=ef0c5082bdecc69867f59c85ad19932c0158edc9;hb=303060616fe3ecc18280f0c217e1b3c102a6cf08;hp=30ee8ca4cdf9c31a4c3840962eff71f24ea59682;hpb=7b88eb9cbb0c1342a6480820450644708aed019c;p=perl%2Fmodules%2Fre-engine-Hooks.git diff --git a/Hooks.xs b/Hooks.xs index 30ee8ca..ef0c508 100644 --- a/Hooks.xs +++ b/Hooks.xs @@ -17,6 +17,14 @@ # define SvPV_const(S, L) SvPV(S, L) #endif +#ifdef USE_ITHREADS +# define REH_LOCK(M) MUTEX_LOCK(M) +# define REH_UNLOCK(M) MUTEX_UNLOCK(M) +#else +# define REH_LOCK(M) NOOP +# define REH_UNLOCK(M) NOOP +#endif + /* --- Lexical hints ------------------------------------------------------- */ STATIC U32 reh_hash = 0; @@ -50,16 +58,21 @@ STATIC SV *reh_hint(pTHX) { typedef struct reh_action { struct reh_action *next; - reh_comp_hook comp; - reh_exec_hook exec; + reh_config cbs; const char *key; STRLEN klen; } reh_action; STATIC reh_action *reh_action_list = 0; +#ifdef USE_ITHREADS + +STATIC perl_mutex reh_action_list_mutex; + +#endif /* USE_ITHREADS */ + #undef reh_register -void reh_register(pTHX_ const char *key, reh_comp_hook comp, reh_exec_hook exec) { +void reh_register(pTHX_ const char *key, reh_config *cfg) { reh_action *a; char *key_dup; STRLEN i, len; @@ -73,13 +86,14 @@ void reh_register(pTHX_ const char *key, reh_comp_hook comp, reh_exec_hook exec) key_dup[len] = '\0'; a = PerlMemShared_malloc(sizeof *a); - a->next = reh_action_list; - a->comp = comp; - a->exec = exec; + a->cbs = *cfg; a->key = key_dup; a->klen = len; + REH_LOCK(&reh_action_list_mutex); + a->next = reh_action_list; reh_action_list = a; + REH_UNLOCK(&reh_action_list_mutex); return; } @@ -94,12 +108,16 @@ void reh_call_comp_hook(pTHX_ regexp *rx, regnode *node) { const char *keys = SvPV_const(hint, len); reh_action *a; - for (a = reh_action_list; a; a = a->next) { - if (a->comp) { + REH_LOCK(&reh_action_list_mutex); + a = reh_action_list; + REH_UNLOCK(&reh_action_list_mutex); + + for (; a; a = a->next) { + if (a->cbs.comp) { char *p = strstr(keys, a->key); if (p && (p + a->klen <= keys + len) && p[a->klen] == ' ') - a->comp(aTHX_ rx, node); + a->cbs.comp(aTHX_ rx, node); } } } @@ -113,12 +131,16 @@ void reh_call_exec_hook(pTHX_ regexp *rx, regnode *node, regmatch_info *reginfo, const char *keys = SvPV_const(hint, len); reh_action *a; - for (a = reh_action_list; a; a = a->next) { - if (a->exec) { + REH_LOCK(&reh_action_list_mutex); + a = reh_action_list; + REH_UNLOCK(&reh_action_list_mutex); + + for (; a; a = a->next) { + if (a->cbs.exec) { char *p = strstr(keys, a->key); if (p && (p + a->klen <= keys + len) && p[a->klen] == ' ') - a->exec(aTHX_ rx, node, reginfo, st); + a->cbs.exec(aTHX_ rx, node, reginfo, st); } } } @@ -178,12 +200,12 @@ reh_re_compile(pTHX_ SV * const pattern, U32 flags) return RX; } -const struct regexp_engine reh_regexp_engine = { - reh_re_compile, - reh_regexec, - reh_re_intuit_start, - reh_re_intuit_string, - reh_regfree, +const struct regexp_engine reh_regexp_engine = { + reh_re_compile, + reh_regexec, + reh_re_intuit_start, + reh_re_intuit_string, + reh_regfree, reh_reg_numbered_buff_fetch, reh_reg_numbered_buff_store, reh_reg_numbered_buff_length, @@ -191,7 +213,7 @@ const struct regexp_engine reh_regexp_engine = { reh_reg_named_buff_iter, reh_reg_qr_package, #if defined(USE_ITHREADS) - reh_regdupe + reh_regdupe #endif }; @@ -201,6 +223,15 @@ MODULE = re::engine::Hooks PACKAGE = re::engine::Hooks PROTOTYPES: ENABLE +BOOT: +{ +#ifdef USE_ITHREADS + MUTEX_INIT(&reh_action_list_mutex); +#endif + + PERL_HASH(reh_hash, __PACKAGE__, __PACKAGE_LEN__); +} + void _ENGINE() PROTOTYPE: @@ -212,10 +243,13 @@ _registered(SV *key) PROTOTYPE: $ PREINIT: SV *ret = NULL; - reh_action *a = reh_action_list; + reh_action *a; STRLEN len; const char *s; PPCODE: + REH_LOCK(&reh_action_list_mutex); + a = reh_action_list; + REH_UNLOCK(&reh_action_list_mutex); s = SvPV_const(key, len); while (a && !ret) { if (a->klen == len && memcmp(a->key, s, len) == 0)