Skip to content

Commit

Permalink
REPL: Try to fix intermittent hang during precompile (JuliaLang#51891)
Browse files Browse the repository at this point in the history
I was intermittently observing the REPL precompile process not
finishing. What I believe was happening is the following:

1. The last line of the precompile script is
`cd("complete_path\t\t$CTRL_C`
2. As soon as child julia sees the `CTRL_C`, the prompt is terminated,
and a new prompt is echod.
3. The parent julia tries to complete the line by sending `\n`, and
immediately returns, because the child has already written a new prompt.
4. The child reads the `\n` and enters raw mode (ignoring things like
^D).
5. The parent tries to write `^D` to complete the process, but because
the child is still processing the `\n`, this `^D` is ignored and the
process hangs.

Try to fix this by not writing the superfluous `\n` if the precompile
line ends in `^C`.
  • Loading branch information
Keno committed Oct 27, 2023
1 parent 8a9476f commit f235291
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions stdlib/REPL/src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ foo(x) = 1
@time @eval foo(1)
; pwd
$CTRL_C
$CTRL_R$CTRL_C
$CTRL_R$CTRL_C#
? reinterpret
using Ra\t$CTRL_C
\\alpha\t$CTRL_C
Expand Down Expand Up @@ -93,6 +93,7 @@ generate_precompile_statements() = try
Sys.iswindows() && (sleep(0.1); yield(); yield()) # workaround hang - probably a libuv issue?
write(output_copy, l)
end
write(debug_output, "\n#### EOF ####\n")
catch ex
if !(ex isa Base.IOError && ex.code == Base.UV_EIO)
rethrow() # ignore EIO on ptm after pts dies
Expand All @@ -117,7 +118,10 @@ generate_precompile_statements() = try
bytesavailable(output_copy) > 0 && readavailable(output_copy)
# push our input
write(debug_output, "\n#### inputting statement: ####\n$(repr(l))\n####\n")
write(ptm, l, "\n")
# If the line ends with a CTRL_C, don't write an extra newline, which would
# cause a second empty prompt. Our code below expects one new prompt per
# input line and can race out of sync with the unexpected second line.
endswith(l, CTRL_C) ? write(ptm, l) : write(ptm, l, "\n")
readuntil(output_copy, "\n")
# wait for the next prompt-like to appear
readuntil(output_copy, "\n")
Expand All @@ -131,6 +135,7 @@ generate_precompile_statements() = try
sleep(0.1)
end
end
write(debug_output, "\n#### COMPLETED - Closing REPL ####\n")
write(ptm, "$CTRL_D")
wait(tee)
success(p) || Base.pipeline_error(p)
Expand Down

0 comments on commit f235291

Please sign in to comment.