Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 40 additions & 47 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ function register_restored_modules(sv::SimpleVector, pkg::PkgId, path::String)
end

function run_package_callbacks(modkey::PkgId)
run_extension_callbacks(modkey)
assert_havelock(require_lock)
unlock(require_lock)
try
Expand Down Expand Up @@ -1204,55 +1205,51 @@ function run_extension_callbacks(extid::ExtensionId)
return succeeded
end

function run_extension_callbacks()
function run_extension_callbacks(pkgid::PkgId)
assert_havelock(require_lock)
loaded_triggers = collect(intersect(keys(Base.loaded_modules), keys(Base.EXT_DORMITORY)))
sort!(loaded_triggers; by=x->x.uuid)
for pkgid in loaded_triggers
# take ownership of extids that depend on this pkgid
extids = pop!(EXT_DORMITORY, pkgid, nothing)
extids === nothing && continue
for extid in extids
if extid.ntriggers > 0
# It is possible that pkgid was loaded in an environment
# below the one of the parent. This will cause a load failure when the
# pkg ext tries to load the triggers. Therefore, check this first
# before loading the pkg ext.
pkgenv = identify_package_env(extid.id, pkgid.name)
ext_not_allowed_load = false
if pkgenv === nothing
# take ownership of extids that depend on this pkgid
extids = pop!(EXT_DORMITORY, pkgid, nothing)
extids === nothing && return
for extid in extids
if extid.ntriggers > 0
# It is possible that pkgid was loaded in an environment
# below the one of the parent. This will cause a load failure when the
# pkg ext tries to load the triggers. Therefore, check this first
# before loading the pkg ext.
pkgenv = identify_package_env(extid.id, pkgid.name)
ext_not_allowed_load = false
if pkgenv === nothing
ext_not_allowed_load = true
else
pkg, env = pkgenv
path = locate_package(pkg, env)
if path === nothing
ext_not_allowed_load = true
else
pkg, env = pkgenv
path = Base.locate_package(pkg, env)
if path === nothing
ext_not_allowed_load = true
end
end
if ext_not_allowed_load
@debug "Extension $(extid.id.name) of $(extid.parentid.name) will not be loaded \
since $(pkgid.name) loaded in environment lower in load path"
# indicate extid is expected to fail
extid.ntriggers *= -1
else
# indicate pkgid is loaded
extid.ntriggers -= 1
end
end
if extid.ntriggers < 0
# indicate pkgid is loaded
extid.ntriggers += 1
succeeded = false
if ext_not_allowed_load
@debug "Extension $(extid.id.name) of $(extid.parentid.name) will not be loaded \
since $(pkgid.name) loaded in environment lower in load path"
# indicate extid is expected to fail
extid.ntriggers *= -1
else
succeeded = true
end
if extid.ntriggers == 0
# actually load extid, now that all dependencies are met,
# and record the result
succeeded = succeeded && run_extension_callbacks(extid)
succeeded || push!(EXT_DORMITORY_FAILED, extid)
# indicate pkgid is loaded
extid.ntriggers -= 1
end
end
if extid.ntriggers < 0
# indicate pkgid is loaded
extid.ntriggers += 1
succeeded = false
else
succeeded = true
end
if extid.ntriggers == 0
# actually load extid, now that all dependencies are met,
# and record the result
succeeded = succeeded && run_extension_callbacks(extid)
succeeded || push!(EXT_DORMITORY_FAILED, extid)
end
end
return
end
Expand All @@ -1276,7 +1273,7 @@ function retry_load_extensions()
end
prepend!(EXT_DORMITORY_FAILED, failed)
end
nothing
return
end

"""
Expand Down Expand Up @@ -1669,10 +1666,6 @@ function _require_prelocked(uuidkey::PkgId, env=nothing)
else
newm = root_module(uuidkey)
end
# Load extensions when not precompiling and not in a nested package load
if JLOptions().incremental == 0 && isempty(package_locks)
run_extension_callbacks()
end
return newm
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ using HasExtensions: HasExtensions, HasExtensionsStruct
using ExtDep: ExtDepStruct
# Loading ExtDep makes the extension "Extension" load

const m = Base.get_extension(HasExtensions, :Extension)
m isa Module || error("extension not loaded during precompilation")

function do_something()
HasExtensions.foo(HasExtensionsStruct()) == 1 || error()
HasExtensions.foo(ExtDepStruct()) == 2 || error()
return true
end

function __init__()
m = Base.get_extension(HasExtensions, :Extension)
m isa Module || error("extension not loaded during __init__")
end

end # module