On Mon, Jan 4, 2016 at 12:43 PM, Zoltán Herczeg <[email protected]> wrote:
> However, if you compile the same pattern multiple times in different threads 
> there will be (unrecoverable) memory leaks. The compilation which finishes 
> last overwrites the previous data. This cannot happen with single thread 
> compilation, since the compiler checks whether a given mode is compiled 
> before (the appropriate entry is non-NULL). However, if the compilation is in 
> progress, and the NULL has not been changed yet (kind of a racing condition), 
> it starts another compilation. I think to avoid such situations is the 
> application responsibility.

It is, and I agree. However the scenario I depicted was slightly
different. In PCRE1 I could have something like this:

/* global state */
pcre *code; /* initialized the results of a pcre_compile2 */
mutex m;
pcre_extra *extra; /* initialized to NULL */

With this one can safely have multiple threads matching using the same
code. The match would look like something like this:

pcre_extra *local_copy;
lock(mutex);
local_copy = extra;
unlock(mutex);
pcre_exec(code, local_copy, ...);

Now, if one thread also wanted to study/jit compile, it could do:

lock(mutex);
extra = pcre_study(code, ...);
unlock(mutex);
/* then proceed to match as usual */

Now in PCRE2 this possibility gets prevented by the fact that there
will surely be data races between one thread inspecting the pcre2_code
data structure for checking whether there's jit support available, and
another thread jit-compiling and setting the jit fields in the same
data structure.

For now, I've solved this problem by employing an external read/write
mutex -- threads which are matching match under a read mutex, threads
which want to jit-compile need to acquire the write mutex. But I feel
this may worsen the overall performances.

Thanks for the help,
-- 
Giuseppe D'Angelo

-- 
## List details at https://lists.exim.org/mailman/listinfo/pcre-dev 

Reply via email to