Skip to content

Commit 901a3a5

Browse files
committed
Revert "fix #41546, make using thread-safe (#41602)"
This reverts commit e3255ef.
1 parent 21a2784 commit 901a3a5

File tree

4 files changed

+27
-84
lines changed

4 files changed

+27
-84
lines changed

base/loading.jl

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

33
# Base.require is the implementation for the `import` statement
4-
const require_lock = ReentrantLock()
54

65
# Cross-platform case-sensitive path canonicalization
76

@@ -130,7 +129,6 @@ end
130129
const ns_dummy_uuid = UUID("fe0723d6-3a44-4c41-8065-ee0f42c8ceab")
131130

132131
function dummy_uuid(project_file::String)
133-
@lock require_lock begin
134132
cache = LOADING_CACHE[]
135133
if cache !== nothing
136134
uuid = get(cache.dummy_uuid, project_file, nothing)
@@ -146,7 +144,6 @@ function dummy_uuid(project_file::String)
146144
cache.dummy_uuid[project_file] = uuid
147145
end
148146
return uuid
149-
end
150147
end
151148

152149
## package path slugs: turning UUID + SHA1 into a pair of 4-byte "slugs" ##
@@ -239,7 +236,8 @@ struct TOMLCache
239236
end
240237
const TOML_CACHE = TOMLCache(TOML.Parser(), Dict{String, Dict{String, Any}}())
241238

242-
parsed_toml(project_file::AbstractString) = parsed_toml(project_file, TOML_CACHE, require_lock)
239+
const TOML_LOCK = ReentrantLock()
240+
parsed_toml(project_file::AbstractString) = parsed_toml(project_file, TOML_CACHE, TOML_LOCK)
243241
function parsed_toml(project_file::AbstractString, toml_cache::TOMLCache, toml_lock::ReentrantLock)
244242
lock(toml_lock) do
245243
cache = LOADING_CACHE[]
@@ -339,15 +337,13 @@ Use [`dirname`](@ref) to get the directory part and [`basename`](@ref)
339337
to get the file name part of the path.
340338
"""
341339
function pathof(m::Module)
342-
@lock require_lock begin
343-
pkgid = get(module_keys, m, nothing)
340+
pkgid = get(Base.module_keys, m, nothing)
344341
pkgid === nothing && return nothing
345-
origin = get(pkgorigins, pkgid, nothing)
342+
origin = get(Base.pkgorigins, pkgid, nothing)
346343
origin === nothing && return nothing
347344
path = origin.path
348345
path === nothing && return nothing
349346
return fixup_stdlib_path(path)
350-
end
351347
end
352348

353349
"""
@@ -370,7 +366,7 @@ julia> pkgdir(Foo, "src", "file.jl")
370366
The optional argument `paths` requires at least Julia 1.7.
371367
"""
372368
function pkgdir(m::Module, paths::String...)
373-
rootmodule = moduleroot(m)
369+
rootmodule = Base.moduleroot(m)
374370
path = pathof(rootmodule)
375371
path === nothing && return nothing
376372
return joinpath(dirname(dirname(path)), paths...)
@@ -387,7 +383,6 @@ const preferences_names = ("JuliaLocalPreferences.toml", "LocalPreferences.toml"
387383
# - `true`: `env` is an implicit environment
388384
# - `path`: the path of an explicit project file
389385
function env_project_file(env::String)::Union{Bool,String}
390-
@lock require_lock begin
391386
cache = LOADING_CACHE[]
392387
if cache !== nothing
393388
project_file = get(cache.env_project_file, env, nothing)
@@ -411,7 +406,6 @@ function env_project_file(env::String)::Union{Bool,String}
411406
cache.env_project_file[env] = project_file
412407
end
413408
return project_file
414-
end
415409
end
416410

417411
function project_deps_get(env::String, name::String)::Union{Nothing,PkgId}
@@ -479,7 +473,6 @@ end
479473

480474
# find project file's corresponding manifest file
481475
function project_file_manifest_path(project_file::String)::Union{Nothing,String}
482-
@lock require_lock begin
483476
cache = LOADING_CACHE[]
484477
if cache !== nothing
485478
manifest_path = get(cache.project_file_manifest_path, project_file, missing)
@@ -508,7 +501,6 @@ function project_file_manifest_path(project_file::String)::Union{Nothing,String}
508501
cache.project_file_manifest_path[project_file] = manifest_path
509502
end
510503
return manifest_path
511-
end
512504
end
513505

514506
# given a directory (implicit env from LOAD_PATH) and a name,
@@ -696,7 +688,7 @@ function implicit_manifest_deps_get(dir::String, where::PkgId, name::String)::Un
696688
@assert where.uuid !== nothing
697689
project_file = entry_point_and_project_file(dir, where.name)[2]
698690
project_file === nothing && return nothing # a project file is mandatory for a package with a uuid
699-
proj = project_file_name_uuid(project_file, where.name)
691+
proj = project_file_name_uuid(project_file, where.name, )
700692
proj == where || return nothing # verify that this is the correct project file
701693
# this is the correct project, so stop searching here
702694
pkg_uuid = explicit_project_deps_get(project_file, name)
@@ -761,26 +753,19 @@ function _include_from_serialized(path::String, depmods::Vector{Any})
761753
if isa(sv, Exception)
762754
return sv
763755
end
764-
sv = sv::SimpleVector
765-
restored = sv[1]::Vector{Any}
766-
for M in restored
767-
M = M::Module
768-
if isdefined(M, Base.Docs.META)
769-
push!(Base.Docs.modules, M)
770-
end
771-
if parentmodule(M) === M
772-
register_root_module(M)
773-
end
774-
end
775-
inits = sv[2]::Vector{Any}
776-
if !isempty(inits)
777-
unlock(require_lock) # temporarily _unlock_ during these callbacks
778-
try
779-
ccall(:jl_init_restored_modules, Cvoid, (Any,), inits)
780-
finally
781-
lock(require_lock)
756+
restored = sv[1]
757+
if !isa(restored, Exception)
758+
for M in restored::Vector{Any}
759+
M = M::Module
760+
if isdefined(M, Base.Docs.META)
761+
push!(Base.Docs.modules, M)
762+
end
763+
if parentmodule(M) === M
764+
register_root_module(M)
765+
end
782766
end
783767
end
768+
isassigned(sv, 2) && ccall(:jl_init_restored_modules, Cvoid, (Any,), sv[2])
784769
return restored
785770
end
786771

@@ -877,7 +862,7 @@ function _require_search_from_serialized(pkg::PkgId, sourcepath::String)
877862
end
878863

879864
# to synchronize multiple tasks trying to import/using something
880-
const package_locks = Dict{PkgId,Threads.Condition}()
865+
const package_locks = Dict{PkgId,Condition}()
881866

882867
# to notify downstream consumers that a module was successfully loaded
883868
# Callbacks take the form (mod::Base.PkgId) -> nothing.
@@ -900,9 +885,7 @@ function _include_dependency(mod::Module, _path::AbstractString)
900885
path = normpath(joinpath(dirname(prev), _path))
901886
end
902887
if _track_dependencies[]
903-
@lock require_lock begin
904888
push!(_require_dependencies, (mod, path, mtime(path)))
905-
end
906889
end
907890
return path, prev
908891
end
@@ -974,7 +957,6 @@ For more details regarding code loading, see the manual sections on [modules](@r
974957
[parallel computing](@ref code-availability).
975958
"""
976959
function require(into::Module, mod::Symbol)
977-
@lock require_lock begin
978960
LOADING_CACHE[] = LoadingCache()
979961
try
980962
uuidkey = identify_package(into, String(mod))
@@ -1016,7 +998,6 @@ function require(into::Module, mod::Symbol)
1016998
finally
1017999
LOADING_CACHE[] = nothing
10181000
end
1019-
end
10201001
end
10211002

10221003
mutable struct PkgOrigin
@@ -1028,7 +1009,6 @@ PkgOrigin() = PkgOrigin(nothing, nothing)
10281009
const pkgorigins = Dict{PkgId,PkgOrigin}()
10291010

10301011
function require(uuidkey::PkgId)
1031-
@lock require_lock begin
10321012
if !root_module_exists(uuidkey)
10331013
cachefile = _require(uuidkey)
10341014
if cachefile !== nothing
@@ -1040,19 +1020,15 @@ function require(uuidkey::PkgId)
10401020
end
10411021
end
10421022
return root_module(uuidkey)
1043-
end
10441023
end
10451024

10461025
const loaded_modules = Dict{PkgId,Module}()
10471026
const module_keys = IdDict{Module,PkgId}() # the reverse
10481027

1049-
is_root_module(m::Module) = @lock require_lock haskey(module_keys, m)
1050-
root_module_key(m::Module) = @lock require_lock module_keys[m]
1028+
is_root_module(m::Module) = haskey(module_keys, m)
1029+
root_module_key(m::Module) = module_keys[m]
10511030

10521031
function register_root_module(m::Module)
1053-
# n.b. This is called from C after creating a new module in `Base.__toplevel__`,
1054-
# instead of adding them to the binding table there.
1055-
@lock require_lock begin
10561032
key = PkgId(m, String(nameof(m)))
10571033
if haskey(loaded_modules, key)
10581034
oldm = loaded_modules[key]
@@ -1062,7 +1038,6 @@ function register_root_module(m::Module)
10621038
end
10631039
loaded_modules[key] = m
10641040
module_keys[m] = key
1065-
end
10661041
nothing
10671042
end
10681043

@@ -1078,13 +1053,12 @@ using Base
10781053
end
10791054

10801055
# get a top-level Module from the given key
1081-
root_module(key::PkgId) = @lock require_lock loaded_modules[key]
1056+
root_module(key::PkgId) = loaded_modules[key]
10821057
root_module(where::Module, name::Symbol) =
10831058
root_module(identify_package(where, String(name)))
1084-
maybe_root_module(key::PkgId) = @lock require_lock get(loaded_modules, key, nothing)
10851059

1086-
root_module_exists(key::PkgId) = @lock require_lock haskey(loaded_modules, key)
1087-
loaded_modules_array() = @lock require_lock collect(values(loaded_modules))
1060+
root_module_exists(key::PkgId) = haskey(loaded_modules, key)
1061+
loaded_modules_array() = collect(values(loaded_modules))
10881062

10891063
function unreference_module(key::PkgId)
10901064
if haskey(loaded_modules, key)
@@ -1103,7 +1077,7 @@ function _require(pkg::PkgId)
11031077
wait(loading)
11041078
return
11051079
end
1106-
package_locks[pkg] = Threads.Condition(require_lock)
1080+
package_locks[pkg] = Condition()
11071081

11081082
last = toplevel_load[]
11091083
try
@@ -1171,12 +1145,10 @@ function _require(pkg::PkgId)
11711145
if uuid !== old_uuid
11721146
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), __toplevel__, uuid)
11731147
end
1174-
unlock(require_lock)
11751148
try
11761149
include(__toplevel__, path)
11771150
return
11781151
finally
1179-
lock(require_lock)
11801152
if uuid !== old_uuid
11811153
ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), __toplevel__, old_uuid)
11821154
end

base/toml_parser.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ function Parser(str::String; filepath=nothing)
104104
IdSet{TOMLDict}(), # defined_tables
105105
root,
106106
filepath,
107-
isdefined(Base, :maybe_root_module) ? Base.maybe_root_module(DATES_PKGID) : nothing,
107+
isdefined(Base, :loaded_modules) ? get(Base.loaded_modules, DATES_PKGID, nothing) : nothing,
108108
)
109109
startup(l)
110110
return l

src/dump.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,8 @@ static jl_array_t *jl_finalize_deserializer(jl_serializer_state *s, arraylist_t
22032203

22042204
JL_DLLEXPORT void jl_init_restored_modules(jl_array_t *init_order)
22052205
{
2206+
if (!init_order)
2207+
return;
22062208
int i, l = jl_array_len(init_order);
22072209
for (i = 0; i < l; i++) {
22082210
jl_value_t *mod = jl_array_ptr_ref(init_order, i);
@@ -2655,9 +2657,6 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array)
26552657
jl_recache_other(); // make all of the other objects identities correct (needs to be after insert methods)
26562658
htable_free(&uniquing_table);
26572659
jl_array_t *init_order = jl_finalize_deserializer(&s, tracee_list); // done with f and s (needs to be after recache)
2658-
if (init_order == NULL)
2659-
init_order = (jl_array_t*)jl_an_empty_vec_any;
2660-
assert(jl_isa((jl_value_t*)init_order, jl_array_any_type));
26612660

26622661
JL_GC_PUSH4(&init_order, &restored, &external_backedges, &external_edges);
26632662
jl_gc_enable(en); // subtyping can allocate a lot, not valid before recache-other

test/threads_exec.jl

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -912,31 +912,3 @@ end
912912
@test reproducible_rand(r, 10) == val
913913
end
914914
end
915-
916-
# issue #41546, thread-safe package loading
917-
@testset "package loading" begin
918-
ch = Channel{Bool}(nthreads())
919-
barrier = Base.Event()
920-
old_act_proj = Base.ACTIVE_PROJECT[]
921-
try
922-
pushfirst!(LOAD_PATH, "@")
923-
Base.ACTIVE_PROJECT[] = joinpath(@__DIR__, "TestPkg")
924-
@sync begin
925-
for _ in 1:nthreads()
926-
Threads.@spawn begin
927-
put!(ch, true)
928-
wait(barrier)
929-
@eval using TestPkg
930-
end
931-
end
932-
for _ in 1:nthreads()
933-
take!(ch)
934-
end
935-
notify(barrier)
936-
end
937-
@test Base.root_module(@__MODULE__, :TestPkg) isa Module
938-
finally
939-
Base.ACTIVE_PROJECT[] = old_act_proj
940-
popfirst!(LOAD_PATH)
941-
end
942-
end

0 commit comments

Comments
 (0)