Skip to content

Commit 1c294dd

Browse files
author
KristofferC
committed
record dependencies when requiring a package and also mark those deps as explicitly loaded
this is important for packages in the sysimage whose dependencies should also be marked as loaded when they themselves are loaded
1 parent 488d941 commit 1c294dd

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

base/loading.jl

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
14581458
# TODO: Better error message if this lookup fails?
14591459
uuid_trigger = UUID(totaldeps[trigger]::String)
14601460
trigger_id = PkgId(uuid_trigger, trigger)
1461-
if !haskey(explicit_loaded_modules, trigger_id) || haskey(package_locks, trigger_id)
1461+
if !in(trigger_id, explicit_loaded_modules) || haskey(package_locks, trigger_id)
14621462
trigger1 = get!(Vector{ExtensionId}, EXT_DORMITORY, trigger_id)
14631463
push!(trigger1, gid)
14641464
else
@@ -2148,6 +2148,8 @@ function require(into::Module, mod::Symbol)
21482148
end
21492149
end
21502150

2151+
const require_map = Dict{PkgId, Set{PkgId}}()
2152+
21512153
function __require(into::Module, mod::Symbol)
21522154
@lock require_lock begin
21532155
LOADING_CACHE[] = LoadingCache()
@@ -2192,7 +2194,13 @@ function __require(into::Module, mod::Symbol)
21922194
path = binpack(uuidkey)
21932195
push!(_require_dependencies, (into, path, UInt64(0), UInt32(0), 0.0))
21942196
end
2195-
return _require_prelocked(uuidkey, env)
2197+
push!(get!(Set{PkgId}, require_map, PkgId(into)), uuidkey)
2198+
try
2199+
return _require_prelocked(uuidkey, env)
2200+
catch
2201+
delete!(require_map, PkgId(into))
2202+
rethrow()
2203+
end
21962204
finally
21972205
LOADING_CACHE[] = nothing
21982206
end
@@ -2268,12 +2276,11 @@ function __require_prelocked(uuidkey::PkgId, env=nothing)
22682276
end
22692277
insert_extension_triggers(uuidkey)
22702278
# After successfully loading, notify downstream consumers
2271-
run_package_callbacks(uuidkey)
2279+
update_explicit_loaded_modules(uuidkey)
22722280
else
22732281
m = get(loaded_modules, uuidkey, nothing)
2274-
if m !== nothing && !haskey(explicit_loaded_modules, uuidkey)
2275-
explicit_loaded_modules[uuidkey] = m
2276-
run_package_callbacks(uuidkey)
2282+
if m !== nothing && !in(uuidkey, explicit_loaded_modules)
2283+
update_explicit_loaded_modules(uuidkey)
22772284
end
22782285
newm = root_module(uuidkey)
22792286
end
@@ -2290,7 +2297,7 @@ const pkgorigins = Dict{PkgId,PkgOrigin}()
22902297

22912298
const loaded_modules = Dict{PkgId,Module}()
22922299
# Emptied on Julia start
2293-
const explicit_loaded_modules = Dict{PkgId,Module}()
2300+
const explicit_loaded_modules = Set{PkgId}()
22942301
const loaded_modules_order = Vector{Module}()
22952302
const module_keys = IdDict{Module,PkgId}() # the reverse
22962303

@@ -2313,12 +2320,26 @@ root_module_key(m::Module) = @lock require_lock module_keys[m]
23132320
end
23142321
push!(loaded_modules_order, m)
23152322
loaded_modules[key] = m
2316-
explicit_loaded_modules[key] = m
2323+
update_explicit_loaded_modules(key)
23172324
module_keys[m] = key
23182325
end
23192326
nothing
23202327
end
23212328

2329+
2330+
function update_explicit_loaded_modules(key::PkgId)
2331+
if !in(key, explicit_loaded_modules)
2332+
push!(explicit_loaded_modules, key)
2333+
run_package_callbacks(key)
2334+
deps = get(require_map, key, nothing)
2335+
if deps !== nothing
2336+
for dep in deps
2337+
update_explicit_loaded_modules(dep)
2338+
end
2339+
end
2340+
end
2341+
end
2342+
23222343
register_root_module(Core)
23232344
register_root_module(Base)
23242345
register_root_module(Main)

test/loading.jl

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,18 +1125,17 @@ end
11251125
sysimg_ext_test_code = """
11261126
uuid_key = Base.PkgId(Base.UUID("37e2e46d-f89d-539d-b4ee-838fcccc9c8e"), "LinearAlgebra")
11271127
Base.in_sysimage(uuid_key) || error("LinearAlgebra not in sysimage")
1128-
haskey(Base.explicit_loaded_modules, uuid_key) && error("LinearAlgebra already loaded")
1128+
in(Base.explicit_loaded_modules, uuid_key) && error("LinearAlgebra already loaded")
11291129
using HasExtensions
11301130
Base.get_extension(HasExtensions, :LinearAlgebraExt) === nothing || error("unexpectedly got an extension")
11311131
using LinearAlgebra
1132-
haskey(Base.explicit_loaded_modules, uuid_key) || error("LinearAlgebra not loaded")
1132+
in(Base.explicit_loaded_modules, uuid_key) || error("LinearAlgebra not loaded")
11331133
Base.get_extension(HasExtensions, :LinearAlgebraExt) isa Module || error("expected extension to load")
11341134
"""
11351135
cmd = `$(Base.julia_cmd()) --startup-file=no -e $sysimg_ext_test_code`
11361136
cmd = addenv(cmd, "JULIA_LOAD_PATH" => join([proj, "@stdlib"], sep))
11371137
@test success(cmd)
11381138

1139-
# Failure of loading some extensions when trigger is in the sysimage
11401139
# The test below requires that LinearAlgebra is in the sysimage and that it has not been loaded yet
11411140
# and that it depends on Libdl.
11421141
# If it gets moved out, this test will need to be updated.
@@ -1153,6 +1152,18 @@ end
11531152
"""
11541153
cmd = `$(Base.julia_cmd()) --startup-file=no -e $sysimg_ext_test_code`
11551154
cmd = addenv(cmd, "JULIA_LOAD_PATH" => join([proj_libdlext, "@stdlib"], sep))
1155+
@test success(cmd)
1156+
1157+
# Failure of loading some extensions when loading a precompiled package with a trigger in the sysimage
1158+
sysimg_ext_test_code = """
1159+
uuid_key_la = Base.PkgId(Base.UUID("37e2e46d-f89d-539d-b4ee-838fcccc9c8e"), "LinearAlgebra")
1160+
using GotLibdlExt
1161+
using SparseArrays # loads LinearAlgebra
1162+
haskey(Base.loaded_modules, uuid_key_la) || error("LinearAlgebra not loaded")
1163+
Base.get_extension(GotLibdlExt, :LibdlExt) isa Module || error("expected extension to load")
1164+
"""
1165+
cmd = `$(Base.julia_cmd()) --startup-file=no -e $sysimg_ext_test_code`
1166+
cmd = addenv(cmd, "JULIA_LOAD_PATH" => join([proj_libdlext, "@stdlib"], sep))
11561167
@test_broken success(cmd)
11571168

11581169
# Extensions in implicit environments

0 commit comments

Comments
 (0)