]> git.vpit.fr Git - perl/modules/re-engine-Hooks.git/blobdiff - Hooks.xs
No trailing whitespace
[perl/modules/re-engine-Hooks.git] / Hooks.xs
index 30ee8ca4cdf9c31a4c3840962eff71f24ea59682..ef0c5082bdecc69867f59c85ad19932c0158edc9 100644 (file)
--- a/Hooks.xs
+++ b/Hooks.xs
 # 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)