]> git.vpit.fr Git - perl/modules/re-engine-Hooks.git/blobdiff - Hooks.xs
Switch to a config-object based interface
[perl/modules/re-engine-Hooks.git] / Hooks.xs
index 30ee8ca4cdf9c31a4c3840962eff71f24ea59682..0c9510a4c05d3895a5bf7f04afde9e0c2cc3d9e0 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);
    }
   }
  }
@@ -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)