]> git.vpit.fr Git - perl/modules/re-engine-Hooks.git/commitdiff
Protect the global linked list by a mutex
authorVincent Pit <vince@profvince.com>
Fri, 30 Mar 2012 20:00:18 +0000 (22:00 +0200)
committerVincent Pit <vince@profvince.com>
Fri, 30 Mar 2012 20:00:18 +0000 (22:00 +0200)
Hooks.xs

index 30ee8ca4cdf9c31a4c3840962eff71f24ea59682..eddf6ad62bbeac7ebc1e97bad99b2d24426faf3e 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;
@@ -58,6 +66,12 @@ typedef struct 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) {
  reh_action *a;
@@ -73,13 +87,15 @@ 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->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,7 +110,11 @@ 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) {
+  REH_LOCK(&reh_action_list_mutex);
+  a = reh_action_list;
+  REH_UNLOCK(&reh_action_list_mutex);
+
+  for (; a; a = a->next) {
    if (a->comp) {
     char *p = strstr(keys, a->key);
 
@@ -113,7 +133,11 @@ 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) {
+  REH_LOCK(&reh_action_list_mutex);
+  a = reh_action_list;
+  REH_UNLOCK(&reh_action_list_mutex);
+
+  for (; a; a = a->next) {
    if (a->exec) {
     char *p = strstr(keys, a->key);
 
@@ -201,6 +225,13 @@ MODULE = re::engine::Hooks          PACKAGE = re::engine::Hooks
 
 PROTOTYPES: ENABLE
 
+BOOT:
+{
+#ifdef USE_ITHREADS
+ MUTEX_INIT(&reh_action_list_mutex);
+#endif
+}
+
 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)