grep-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Grep-devel] [PATCH 4/4] pcresearch: thread safety


From: Zev Weiss
Subject: [Grep-devel] [PATCH 4/4] pcresearch: thread safety
Date: Sun, 25 Dec 2016 02:57:09 -0600

* src/pcresearch.c (pcre_comp): New struct to hold previously-global
state.
(jit_exec): Operate on a pcre_comp parameter instead of global state.
(Pcompile): Allocate and return a pcre_comp instead of setting global
variables.
(Pexecute): Operate on a pcre_comp parameter instead of global state.
---
 src/pcresearch.c | 88 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 41 deletions(-)

diff --git a/src/pcresearch.c b/src/pcresearch.c
index 54d9430..5bc9328 100644
--- a/src/pcresearch.c
+++ b/src/pcresearch.c
@@ -29,48 +29,57 @@
    in pcre_exec.  */
 enum { NSUB = 300 };
 
-/* Compiled internal form of a Perl regular expression.  */
-static pcre *cre;
-
-/* Additional information about the pattern.  */
-static pcre_extra *extra;
-
 # ifndef PCRE_STUDY_JIT_COMPILE
 #  define PCRE_STUDY_JIT_COMPILE 0
 # endif
 
+struct pcre_comp
+{
+  /* Compiled internal form of a Perl regular expression.  */
+  pcre *cre;
+
+  /* Additional information about the pattern.  */
+  pcre_extra *extra;
+
 # if PCRE_STUDY_JIT_COMPILE
-/* Maximum size of the JIT stack.  */
-static int jit_stack_size;
+  /* Maximum size of the JIT stack.  */
+  int jit_stack_size;
 # endif
 
+  /* Table, indexed by ! (flag & PCRE_NOTBOL), of whether the empty
+     string matches when that flag is used.  */
+  int empty_match[2];
+
+  pcre_jit_stack *jit_stack;
+};
+
+
 /* Match the already-compiled PCRE pattern against the data in SUBJECT,
    of size SEARCH_BYTES and starting with offset SEARCH_OFFSET, with
    options OPTIONS, and storing resulting matches into SUB.  Return
    the (nonnegative) match location or a (negative) error number.  */
 static int
-jit_exec (char const *subject, int search_bytes, int search_offset,
-          int options, int *sub)
+jit_exec (struct pcre_comp *pc, char const *subject, int search_bytes,
+          int search_offset, int options, int *sub)
 {
   while (true)
     {
-      int e = pcre_exec (cre, extra, subject, search_bytes, search_offset,
-                         options, sub, NSUB);
+      int e = pcre_exec (pc->cre, pc->extra, subject, search_bytes,
+                         search_offset, options, sub, NSUB);
 
 # if PCRE_STUDY_JIT_COMPILE
       if (e == PCRE_ERROR_JIT_STACKLIMIT
-          && 0 < jit_stack_size && jit_stack_size <= INT_MAX / 2)
+          && 0 < pc->jit_stack_size && pc->jit_stack_size <= INT_MAX / 2)
         {
-          int old_size = jit_stack_size;
-          int new_size = jit_stack_size = old_size * 2;
-          static pcre_jit_stack *jit_stack;
-          if (jit_stack)
-            pcre_jit_stack_free (jit_stack);
-          jit_stack = pcre_jit_stack_alloc (old_size, new_size);
-          if (!jit_stack)
+          int old_size = pc->jit_stack_size;
+          int new_size = pc->jit_stack_size = old_size * 2;
+          if (pc->jit_stack)
+            pcre_jit_stack_free (pc->jit_stack);
+          pc->jit_stack = pcre_jit_stack_alloc (old_size, new_size);
+          if (!pc->jit_stack)
             die (EXIT_TROUBLE, 0,
                  _("failed to allocate memory for the PCRE JIT stack"));
-          pcre_assign_jit_stack (extra, NULL, jit_stack);
+          pcre_assign_jit_stack (pc->extra, NULL, pc->jit_stack);
           continue;
         }
 # endif
@@ -81,12 +90,6 @@ jit_exec (char const *subject, int search_bytes, int 
search_offset,
 
 #endif
 
-#if HAVE_LIBPCRE
-/* Table, indexed by ! (flag & PCRE_NOTBOL), of whether the empty
-   string matches when that flag is used.  */
-static int empty_match[2];
-#endif
-
 void *
 Pcompile (char const *pattern, size_t size, reg_syntax_t ignored)
 {
@@ -109,6 +112,7 @@ Pcompile (char const *pattern, size_t size, reg_syntax_t 
ignored)
   char *n = re;
   char const *p;
   char const *pnul;
+  struct pcre_comp *pc = xcalloc (1, sizeof (*pc));
 
   if (localeinfo.multibyte)
     {
@@ -151,32 +155,33 @@ Pcompile (char const *pattern, size_t size, reg_syntax_t 
ignored)
   if (match_lines)
     strcpy (n, xsuffix);
 
-  cre = pcre_compile (re, flags, &ep, &e, pcre_maketables ());
-  if (!cre)
+  pc->cre = pcre_compile (re, flags, &ep, &e, pcre_maketables ());
+  if (!pc->cre)
     die (EXIT_TROUBLE, 0, "%s", ep);
 
-  extra = pcre_study (cre, PCRE_STUDY_JIT_COMPILE, &ep);
+  pc->extra = pcre_study (pc->cre, PCRE_STUDY_JIT_COMPILE, &ep);
   if (ep)
     die (EXIT_TROUBLE, 0, "%s", ep);
 
 # if PCRE_STUDY_JIT_COMPILE
-  if (pcre_fullinfo (cre, extra, PCRE_INFO_JIT, &e))
+  if (pcre_fullinfo (pc->cre, pc->extra, PCRE_INFO_JIT, &e))
     die (EXIT_TROUBLE, 0, _("internal error (should never happen)"));
 
   /* The PCRE documentation says that a 32 KiB stack is the default.  */
   if (e)
-    jit_stack_size = 32 << 10;
+    pc->jit_stack_size = 32 << 10;
 # endif
 
   free (re);
 
   int sub[NSUB];
-  empty_match[false] = pcre_exec (cre, extra, "", 0, 0,
-                                  PCRE_NOTBOL, sub, NSUB);
-  empty_match[true] = pcre_exec (cre, extra, "", 0, 0, 0, sub, NSUB);
-#endif /* HAVE_LIBPCRE */
+  pc->empty_match[false] = pcre_exec (pc->cre, pc->extra, "", 0, 0,
+                                      PCRE_NOTBOL, sub, NSUB);
+  pc->empty_match[true] = pcre_exec (pc->cre, pc->extra, "", 0, 0, 0, sub,
+                                     NSUB);
 
-  return NULL;
+  return pc;
+#endif /* HAVE_LIBPCRE */
 }
 
 size_t
@@ -193,6 +198,7 @@ Pexecute (void *vcp, char const *buf, size_t size, size_t 
*match_size,
   char const *line_start = buf;
   int e = PCRE_ERROR_NOMATCH;
   char const *line_end;
+  struct pcre_comp *pc = vcp;
 
   /* The search address to pass to pcre_exec.  This is the start of
      the buffer, or just past the most-recently discovered encoding
@@ -228,7 +234,7 @@ Pexecute (void *vcp, char const *buf, size_t size, size_t 
*match_size,
           if (p == line_end)
             {
               sub[0] = sub[1] = search_offset;
-              e = empty_match[bol];
+              e = pc->empty_match[bol];
               break;
             }
 
@@ -236,7 +242,7 @@ Pexecute (void *vcp, char const *buf, size_t size, size_t 
*match_size,
           if (!bol)
             options |= PCRE_NOTBOL;
 
-          e = jit_exec (subject, line_end - subject, search_offset,
+          e = jit_exec (pc, subject, line_end - subject, search_offset,
                         options, sub);
           if (e != PCRE_ERROR_BADUTF8)
             break;
@@ -251,10 +257,10 @@ Pexecute (void *vcp, char const *buf, size_t size, size_t 
*match_size,
                      This optimization is valid if VALID_BYTES is zero,
                      which means SEARCH_OFFSET is also zero.  */
                   sub[1] = 0;
-                  e = empty_match[bol];
+                  e = pc->empty_match[bol];
                 }
               else
-                e = jit_exec (subject, valid_bytes, search_offset,
+                e = jit_exec (pc, subject, valid_bytes, search_offset,
                               options | PCRE_NO_UTF8_CHECK | PCRE_NOTEOL, sub);
 
               if (e != PCRE_ERROR_NOMATCH)
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]