Skip to content

Commit

Permalink
loading: stop corrupting memory all over the place
Browse files Browse the repository at this point in the history
Regressions introduced by #45607
  • Loading branch information
vtjnash committed Jun 30, 2022
1 parent d0e28af commit 239a1f2
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,9 @@ the form `pkgversion(@__MODULE__)` can be used.
function pkgversion(m::Module)
rootmodule = moduleroot(m)
pkg = PkgId(rootmodule)
pkgorigin = get(pkgorigins, pkg, nothing)
pkgorigin = @lock require_lock begin
get(pkgorigins, pkg, nothing)
end
return pkgorigin === nothing ? nothing : pkgorigin.version
end

Expand Down Expand Up @@ -952,8 +954,8 @@ function _tryrequire_from_serialized(modkey::PkgId, build_id::UInt64)
try
modpath = locate_package(modkey)
modpath === nothing && return nothing
set_pkgorigin_version_path(modkey, String(modpath))
loaded = _require_search_from_serialized(modkey, String(modpath), build_id)
get!(PkgOrigin, pkgorigins, modkey).path = modpath
finally
loading = pop!(package_locks, modkey)
notify(loading, loaded, all=true)
Expand All @@ -971,7 +973,7 @@ end

# loads a precompile cache file, ignoring stale_cachefile tests
# assuming all depmods are already loaded and everything is valid
function _tryrequire_from_serialized(modkey::PkgId, path::String, depmods::Vector{Any})
function _tryrequire_from_serialized(modkey::PkgId, path::String, sourcepath::String, depmods::Vector{Any})
assert_havelock(require_lock)
loaded = nothing
if root_module_exists(modkey)
Expand All @@ -992,6 +994,7 @@ function _tryrequire_from_serialized(modkey::PkgId, path::String, depmods::Vecto
end
package_locks[modkey] = Threads.Condition(require_lock)
try
set_pkgorigin_version_path(modkey, sourcepath)
loaded = _include_from_serialized(modkey, path, depmods)
finally
loading = pop!(package_locks, modkey)
Expand Down Expand Up @@ -1059,7 +1062,7 @@ end
continue
end
modstaledeps = modstaledeps::Vector{Any}
staledeps[i] = (modkey, modpath_to_try, modstaledeps)
staledeps[i] = (modpath, modkey, modpath_to_try, modstaledeps)
modfound = true
break
end
Expand All @@ -1081,8 +1084,8 @@ end
for i in 1:length(staledeps)
dep = staledeps[i]
dep isa Module && continue
modkey, modpath_to_try, modstaledeps = dep::Tuple{PkgId, String, Vector{Any}}
dep = _tryrequire_from_serialized(modkey, modpath_to_try, modstaledeps)
modpath, modkey, modpath_to_try, modstaledeps = dep::Tuple{String, PkgId, String, Vector{Any}}
dep = _tryrequire_from_serialized(modkey, modpath_to_try, modpath, modstaledeps)
if !isa(dep, Module)
@debug "Rejecting cache file $path_to_try because required dependency $modkey failed to load from cache file for $modpath." exception=dep
staledeps = true
Expand Down Expand Up @@ -1324,7 +1327,9 @@ function unreference_module(key::PkgId)
end
end

function set_pkgorigin_version_path(pkg, path)
# whoever takes the package_locks[pkg] must call this function immediately
function set_pkgorigin_version_path(pkg::PkgId, path::Union{String,Nothing})
assert_havelock(require_lock)
pkgorigin = get!(PkgOrigin, pkgorigins, pkg)
if path !== nothing
project_file = locate_project_file(joinpath(dirname(path), ".."))
Expand All @@ -1337,6 +1342,7 @@ function set_pkgorigin_version_path(pkg, path)
end
end
pkgorigin.path = path
nothing
end

# Returns `nothing` or the new(ish) module
Expand All @@ -1356,13 +1362,13 @@ function _require(pkg::PkgId)
toplevel_load[] = false
# perform the search operation to select the module file require intends to load
path = locate_package(pkg)
set_pkgorigin_version_path(pkg, path)
if path === nothing
throw(ArgumentError("""
Package $pkg is required but does not seem to be installed:
- Run `Pkg.instantiate()` to install all recorded dependencies.
"""))
end
set_pkgorigin_version_path(pkg, path)

# attempt to load the module file via the precompile cache locations
if JLOptions().use_compiled_modules != 0
Expand Down Expand Up @@ -1436,6 +1442,7 @@ end

function _require_from_serialized(uuidkey::PkgId, path::String)
@lock require_lock begin
set_pkgorigin_version_path(uuidkey, nothing)
newm = _tryrequire_from_serialized(uuidkey, path)
newm isa Module || throw(newm)
# After successfully loading, notify downstream consumers
Expand Down Expand Up @@ -2160,7 +2167,6 @@ end
@debug "Rejecting cache file $cachefile because dependency $req_key not found."
return true # Won't be able to fulfill dependency
end
set_pkgorigin_version_path(req_key, path)
depmods[i] = (path, req_key, req_build_id)
end
end
Expand Down

0 comments on commit 239a1f2

Please sign in to comment.