Skip to content

Commit 2d9a57a

Browse files
authored
Replace thread-local buffers with task local values (#63)
1 parent dce395c commit 2d9a57a

File tree

1 file changed

+28
-21
lines changed

1 file changed

+28
-21
lines changed

src/URIs.jl

+28-21
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ URI(str::AbstractString; kw...) = isempty(kw) ? parse(URI, str) : URI(URI(str);
9090

9191
# Based on regex from RFC 3986:
9292
# https://tools.ietf.org/html/rfc3986#appendix-B
93-
const uri_reference_regex = RegexAndMatchData[]
9493
function uri_reference_regex_f()
9594
r = RegexAndMatchData(r"""^
9695
(?: ([^:/?#]+) :) ? # 1. scheme
@@ -107,6 +106,33 @@ function uri_reference_regex_f()
107106
r
108107
end
109108

109+
if isdefined(Base, :OncePerTask)
110+
const task_local_regex = OncePerTask{RegexAndMatchData}(uri_reference_regex_f)
111+
else
112+
const uri_reference_regex = RegexAndMatchData[]
113+
function access_threaded(f, v::Vector)
114+
tid = Threads.threadid()
115+
0 < tid <= length(v) || _length_assert()
116+
if @inbounds isassigned(v, tid)
117+
@inbounds x = v[tid]
118+
else
119+
x = f()
120+
@inbounds v[tid] = x
121+
end
122+
return x
123+
end
124+
@noinline _length_assert() = @assert false "0 < tid <= v"
125+
126+
task_local_regex() = access_threaded(uri_reference_regex_f, uri_reference_regex)
127+
128+
function __init__()
129+
nt = isdefined(Base.Threads, :maxthreadid) ? Threads.maxthreadid() : Threads.nthreads()
130+
resize!(empty!(uri_reference_regex), nt)
131+
return
132+
end
133+
end
134+
135+
110136
"""
111137
https://tools.ietf.org/html/rfc3986#section-3
112138
"""
@@ -123,7 +149,7 @@ https://tools.ietf.org/html/rfc3986#section-4.1
123149
"""
124150
function parse_uri_reference(str::Union{String, SubString{String}};
125151
strict = false)
126-
uri_reference_re = access_threaded(uri_reference_regex_f, uri_reference_regex)
152+
uri_reference_re = task_local_regex()
127153
if !exec(uri_reference_re, str)
128154
throw(ParseError("URI contains invalid character"))
129155
end
@@ -684,25 +710,6 @@ end
684710
Base.download(uri::URI, args...) = download(uristring(uri), args...)
685711

686712

687-
function access_threaded(f, v::Vector)
688-
tid = Threads.threadid()
689-
0 < tid <= length(v) || _length_assert()
690-
if @inbounds isassigned(v, tid)
691-
@inbounds x = v[tid]
692-
else
693-
x = f()
694-
@inbounds v[tid] = x
695-
end
696-
return x
697-
end
698-
@noinline _length_assert() = @assert false "0 < tid <= v"
699-
700-
function __init__()
701-
nt = isdefined(Base.Threads, :maxthreadid) ? Threads.maxthreadid() : Threads.nthreads()
702-
resize!(empty!(uri_reference_regex), nt)
703-
return
704-
end
705-
706713
include("deprecate.jl")
707714

708715
end # module

0 commit comments

Comments
 (0)