Skip to content

Commit 1a37227

Browse files
authored
thread safety fix in compiling regexes (#32544)
1 parent f5a50be commit 1a37227

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

base/pcre.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ end
2525

2626
const THREAD_MATCH_CONTEXTS = Ptr{Cvoid}[C_NULL]
2727

28+
PCRE_COMPILE_LOCK = nothing
29+
2830
_tid() = Int(ccall(:jl_threadid, Int16, ())+1)
2931
_nth() = Int(unsafe_load(cglobal(:jl_n_threads, Cint)))
3032

@@ -40,6 +42,7 @@ end
4042
function __init__()
4143
resize!(THREAD_MATCH_CONTEXTS, _nth())
4244
fill!(THREAD_MATCH_CONTEXTS, C_NULL)
45+
global PCRE_COMPILE_LOCK = Threads.SpinLock()
4346
end
4447

4548
# supported options for different use cases

base/regex.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,21 @@ Regex(pattern::AbstractString) = Regex(pattern, DEFAULT_COMPILER_OPTS, DEFAULT_M
6161

6262
function compile(regex::Regex)
6363
if regex.regex == C_NULL
64-
regex.regex = PCRE.compile(regex.pattern, regex.compile_options)
65-
PCRE.jit_compile(regex.regex)
64+
if PCRE.PCRE_COMPILE_LOCK === nothing
65+
regex.regex = PCRE.compile(regex.pattern, regex.compile_options)
66+
PCRE.jit_compile(regex.regex)
67+
else
68+
l = PCRE.PCRE_COMPILE_LOCK::Threads.SpinLock
69+
lock(l)
70+
try
71+
if regex.regex == C_NULL
72+
regex.regex = PCRE.compile(regex.pattern, regex.compile_options)
73+
PCRE.jit_compile(regex.regex)
74+
end
75+
finally
76+
unlock(l)
77+
end
78+
end
6679
end
6780
regex
6881
end

0 commit comments

Comments
 (0)