Skip to content

Commit

Permalink
handle package_locks directly
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth committed Jun 7, 2024
1 parent 7b96a99 commit e7b0044
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions stdlib/REPL/src/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ function check_for_missing_packages_and_run_hooks(ast)
mods = modules_to_be_loaded(ast)
filter!(mod -> isnothing(Base.identify_package(String(mod))), mods) # keep missing modules
if !isempty(mods)
isempty(install_packages_hooks) && Base.require_stdlib(Base.PkgId(Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg"))
isempty(install_packages_hooks) && load_pkg()
for f in install_packages_hooks
Base.invokelatest(f, mods) && return
end
Expand Down Expand Up @@ -1083,6 +1083,18 @@ setup_interface(
) = setup_interface(repl, hascolor, extra_repl_keymap)

const Pkg_pkgid = Base.PkgId(Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")
const Pkg_REPLExt_pkgid = Base.PkgId(Base.UUID("ceef7b17-42e7-5b1c-81d4-4cc4a2494ccf"), "REPLExt")

function load_pkg()
@lock Base.require_lock begin
REPLExt = Base.require_stdlib(Pkg_pkgid, "REPLExt")
# require_stdlib does not guarantee that the `__init__` of the package is done when loading is done async
# but we need to wait for the repl mode to be set up
lock = get(Base.package_locks, Pkg_REPLExt_pkgid.uuid, nothing)
lock !== nothing && wait(lock[2])
return REPLExt
end
end

# This non keyword method can be precompiled which is important
function setup_interface(
Expand Down Expand Up @@ -1171,7 +1183,7 @@ function setup_interface(
on_enter = function (s::MIState)
# This is hit when the user tries to execute a command before the real Pkg mode has been
# switched to. Ok to do this even if Pkg is loading on the other task because of the loading lock.
REPLExt = Base.require_stdlib(Pkg_pkgid, "REPLExt")
REPLExt = load_pkg()
if REPLExt isa Module && isdefined(REPLExt, :PkgCompletionProvider)
for mode in repl.interface.modes
if mode isa LineEdit.Prompt && mode.complete isa REPLExt.PkgCompletionProvider
Expand Down Expand Up @@ -1266,7 +1278,7 @@ function setup_interface(
# load Pkg on another thread if available so that typing in the dummy Pkg prompt
# isn't blocked, but instruct the main REPL task to do the transition via s.async_channel
t_replswitch = Threads.@spawn begin
REPLExt = Base.require_stdlib(Pkg_pkgid, "REPLExt")
REPLExt = load_pkg()
if REPLExt isa Module && isdefined(REPLExt, :PkgCompletionProvider)
put!(s.async_channel,
function (s::MIState, _)
Expand Down

0 comments on commit e7b0044

Please sign in to comment.