Skip to content

Commit 6f39acb

Browse files
REPL: spawn to avoid blocking typing, fix pkg repl transition sequencing (#54785)
Based on #54760 (comment) This changes the `prompt!` design to not consume on the two tasks until inside the lock and spawns the two tasks to avoid blocking typing
1 parent 7c5c724 commit 6f39acb

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

stdlib/REPL/src/LineEdit.jl

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,22 +2823,27 @@ keymap_data(ms::MIState, m::ModalInterface) = keymap_data(state(ms), mode(ms))
28232823

28242824
function prompt!(term::TextTerminal, prompt::ModalInterface, s::MIState = init_state(term, prompt))
28252825
Base.reseteof(term)
2826+
l = Base.ReentrantLock()
2827+
t1 = Threads.@spawn :interactive while true
2828+
wait(s.async_channel)
2829+
status = @lock l begin
2830+
fcn = take!(s.async_channel)
2831+
fcn(s)
2832+
end
2833+
status (:ok, :ignore) || break
2834+
end
28262835
raw!(term, true)
28272836
enable_bracketed_paste(term)
28282837
try
28292838
activate(prompt, s, term, term)
28302839
old_state = mode(s)
2831-
l = Base.ReentrantLock()
2832-
t = @async while true
2833-
fcn = take!(s.async_channel)
2834-
status = @lock l fcn(s)
2835-
status (:ok, :ignore) || break
2836-
end
2837-
Base.errormonitor(t)
2838-
while true
2839-
kmap = keymap(s, prompt)
2840-
fcn = match_input(kmap, s)
2840+
# spawn this because the main repl task is sticky (due to use of @async and _wait2)
2841+
# and we want to not block typing when the repl task thread is busy
2842+
t2 = Threads.@spawn :interactive while true
2843+
eof(term) || peek(term, Char) # wait before locking but don't consume
28412844
@lock l begin
2845+
kmap = keymap(s, prompt)
2846+
fcn = match_input(kmap, s)
28422847
kdata = keymap_data(s, prompt)
28432848
s.current_action = :unknown # if the to-be-run action doesn't update this field,
28442849
# :unknown will be recorded in the last_action field
@@ -2869,7 +2874,10 @@ function prompt!(term::TextTerminal, prompt::ModalInterface, s::MIState = init_s
28692874
end
28702875
end
28712876
end
2877+
return fetch(t2)
28722878
finally
2879+
put!(s.async_channel, Returns(:done))
2880+
wait(t1)
28732881
raw!(term, false) && disable_bracketed_paste(term)
28742882
end
28752883
# unreachable

0 commit comments

Comments
 (0)