extern THREAD_LOCAL regmatch_t pmatch[MAX_MATCH];
+#if defined(USE_PCRE2)
+extern THREAD_LOCAL pcre2_match_data *local_pcre2_match;
+#endif
+
/* "str" is the string that contain the regex to compile.
* "regex" is preallocated memory. After the execution of this function, this
* struct contain the compiled regex.
return 0;
return 1;
#elif defined(USE_PCRE2)
- pcre2_match_data *pm;
int ret;
- pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
ret = preg->mfn(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject),
- 0, 0, pm, NULL);
- pcre2_match_data_free(pm);
+ 0, 0, local_pcre2_match, NULL);
if (ret < 0)
return 0;
return 1;
return 0;
return 1;
#elif defined(USE_PCRE2)
- pcre2_match_data *pm;
int ret;
- pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
ret = preg->mfn(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length,
- 0, 0, pm, NULL);
- pcre2_match_data_free(pm);
+ 0, 0, local_pcre2_match, NULL);
if (ret < 0)
return 0;
return 1;
/* regex trash buffer used by various regex tests */
THREAD_LOCAL regmatch_t pmatch[MAX_MATCH]; /* rm_so, rm_eo for regular expressions */
+#if defined(USE_PCRE2)
+/* avoid alloc/free cycles */
+THREAD_LOCAL pcre2_match_data *local_pcre2_match = NULL;
+#endif
+
int exp_replace(char *dst, unsigned int dst_size, char *src, const char *str, const regmatch_t *matches)
{
char *old_dst = dst;
int ret;
#ifdef USE_PCRE2
PCRE2_SIZE *matches;
- pcre2_match_data *pm;
#else
int matches[MAX_MATCH * 3];
#endif
* space in the matches array.
*/
#ifdef USE_PCRE2
- pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
- ret = preg->mfn(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, options, pm, NULL);
+ ret = preg->mfn(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, options, local_pcre2_match, NULL);
- if (ret < 0) {
- pcre2_match_data_free(pm);
+ if (ret < 0)
return 0;
- }
- matches = pcre2_get_ovector_pointer(pm);
+ matches = pcre2_get_ovector_pointer(local_pcre2_match);
#else
ret = pcre_exec(preg->reg, preg->extra, subject, strlen(subject), 0, options, matches, enmatch * 3);
pmatch[i].rm_so = -1;
pmatch[i].rm_eo = -1;
}
-#ifdef USE_PCRE2
- pcre2_match_data_free(pm);
-#endif
return 1;
#else
int match;
int ret;
#ifdef USE_PCRE2
PCRE2_SIZE *matches;
- pcre2_match_data *pm;
#else
int matches[MAX_MATCH * 3];
#endif
* space in the matches array.
*/
#ifdef USE_PCRE2
- pm = pcre2_match_data_create_from_pattern(preg->reg, NULL);
- ret = preg->mfn(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length, 0, options, pm, NULL);
-
- if (ret < 0) {
- pcre2_match_data_free(pm);
+ ret = preg->mfn(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length, 0, options, local_pcre2_match, NULL);
+ if (ret < 0)
return 0;
- }
- matches = pcre2_get_ovector_pointer(pm);
+ matches = pcre2_get_ovector_pointer(local_pcre2_match);
#else
ret = pcre_exec(preg->reg, preg->extra, subject, length, 0, options, matches, enmatch * 3);
if (ret < 0)
pmatch[i].rm_so = -1;
pmatch[i].rm_eo = -1;
}
-#ifdef USE_PCRE2
- pcre2_match_data_free(pm);
-#endif
return 1;
#else
char old_char = subject[length];
INITCALL0(STG_REGISTER, regex_register_build_options);
+#ifdef USE_PCRE2
+static int init_pcre2_per_thread(void)
+{
+ local_pcre2_match = pcre2_match_data_create(MAX_MATCH - 1, NULL);
+ if (!local_pcre2_match) {
+ ha_alert("Failed to allocate PCRE2 match data context for thread %u.\n", tid);
+ return 0;
+ }
+ return 1;
+}
+
+static void deinit_pcre2_per_thread(void)
+{
+ pcre2_match_data_free(local_pcre2_match);
+}
+
+REGISTER_PER_THREAD_INIT(init_pcre2_per_thread);
+REGISTER_PER_THREAD_DEINIT(deinit_pcre2_per_thread);
+#endif
+
/*
* Local variables:
* c-indent-level: 8