diff options
author | ph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069> | 2020-11-04 17:01:13 +0000 |
---|---|---|
committer | ph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069> | 2020-11-04 17:01:13 +0000 |
commit | a8d49f666674af7d0d2588f324f16cf49c4925b3 (patch) | |
tree | 5512b05b73798c6eeec0cd9415c0df00da021b38 /doc/html | |
parent | b6b478fb743886ab985f8e0470f82075cef474bc (diff) | |
download | pcre2-a8d49f666674af7d0d2588f324f16cf49c4925b3.tar.gz |
Documentation update
git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@1282 6239d852-aaf2-0410-a92c-79f79f948069
Diffstat (limited to 'doc/html')
-rw-r--r-- | doc/html/pcre2api.html | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/doc/html/pcre2api.html b/doc/html/pcre2api.html index 5cd7ae0..e456647 100644 --- a/doc/html/pcre2api.html +++ b/doc/html/pcre2api.html @@ -626,14 +626,15 @@ documentation for more details. <P> In a more complicated situation, where patterns are compiled only when they are first needed, but are still shared between threads, pointers to compiled -patterns must be protected from simultaneous writing by multiple threads, at -least until a pattern has been compiled. The logic can be something like this: +patterns must be protected from simultaneous writing by multiple threads. This +is somewhat tricky to do correctly. If you know that writing to a pointer is +atomic in your environment, you can use logic like this: <pre> Get a read-only (shared) lock (mutex) for pointer if (pointer == NULL) { Get a write (unique) lock for pointer - pointer = pcre2_compile(... + if (pointer == NULL) pointer = pcre2_compile(... } Release the lock Use pointer in pcre2_match() @@ -641,10 +642,39 @@ least until a pattern has been compiled. The logic can be something like this: Of course, testing for compilation errors should also be included in the code. </P> <P> -If JIT is being used, but the JIT compilation is not being done immediately, -(perhaps waiting to see if the pattern is used often enough) similar logic is -required. JIT compilation updates a pointer within the compiled code block, so -a thread must gain unique write access to the pointer before calling +The reason for checking the pointer a second time is as follows: Several +threads may have acquired the shared lock and tested the pointer for being +NULL, but only one of them will be given the write lock, with the rest kept +waiting. The winning thread will compile the pattern and store the result. +After this thread releases the write lock, another thread will get it, and if +it does not retest pointer for being NULL, will recompile the pattern and +overwrite the pointer, creating a memory leak and possibly causing other +issues. +</P> +<P> +In an environment where writing to a pointer may not be atomic, the above logic +is not sufficient. The thread that is doing the compiling may be descheduled +after writing only part of the pointer, which could cause other threads to use +an invalid value. Instead of checking the pointer itself, a separate "pointer +is valid" flag (that can be updated atomically) must be used: +<pre> + Get a read-only (shared) lock (mutex) for pointer + if (!pointer_is_valid) + { + Get a write (unique) lock for pointer + if (!pointer_is_valid) + { + pointer = pcre2_compile(... + pointer_is_valid = TRUE + } + } + Release the lock + Use pointer in pcre2_match() +</pre> +If JIT is being used, but the JIT compilation is not being done immediately +(perhaps waiting to see if the pattern is used often enough), similar logic is +required. JIT compilation updates a value within the compiled code block, so a +thread must gain unique write access to the pointer before calling <b>pcre2_jit_compile()</b>. Alternatively, <b>pcre2_code_copy()</b> or <b>pcre2_code_copy_with_tables()</b> can be used to obtain a private copy of the compiled code before calling the JIT compiler. @@ -3959,7 +3989,7 @@ Cambridge, England. </P> <br><a name="SEC42" href="#TOC1">REVISION</a><br> <P> -Last updated: 05 October 2020 +Last updated: 04 November 2020 <br> Copyright © 1997-2020 University of Cambridge. <br> |