Fix race between spinner animation in weather demo and the network permission prompt

master
Ondřej Hruška 1 day ago
parent de5f536e7d
commit dd2b153bbe
  1. 4
      docs/fs.md
  2. 6
      src/stdlib/perm/prompt.rs
  3. 7
      src/stdlib/tui/output.rs

@ -124,6 +124,10 @@ luna: permission request
- No terminal (piped stdin, cron): the operation is denied for this run and
*nothing* is recorded.
While a prompt is waiting, `tui` output from concurrently running coroutines
(e.g. a spinner animating during the request that triggered the question) is
held back so it cannot overwrite the question, and resumes with the answer.
### `access.json`
Recorded answers live in `$XDG_CONFIG_HOME/luna/access.json` (usually

@ -35,8 +35,12 @@ pub(super) fn prompt_access(script: &str, wants: &str) -> Choice {
if !can_prompt() {
return Choice::NoTty;
}
// The leading clear-line erases anything a concurrent coroutine left on
// the current line before the prompt took the terminal (e.g. a spinner
// frame) — further output is held back by the prompt lock, which the
// caller already holds.
eprint!(
"{APP_NAME}: permission request\n \
"\x1b[2K\r{APP_NAME}: permission request\n \
script: {script}\n \
wants: {wants}\n\
[y] allow once [n] deny once [A] allow always [N] never allow: "

@ -86,7 +86,14 @@ fn style_opt(lua: &Lua, opts: &Opts, key: &str) -> LuaResult<Option<markup::Styl
/// bypass the capture and trash the test runner's output. In normal builds it
/// writes the bytes directly, ignores errors (a broken pipe must not panic
/// the runtime) and flushes (tui.raw is used for `\r` redraws mid-line).
///
/// Serialized with the prompts via [`PROMPT_LOCK`]: while a prompt (inquire
/// or a permission request) owns the terminal, a concurrent coroutine's
/// output — e.g. a spinner's `<clear=line>` redraw, which would erase the
/// prompt's question line — blocks until the prompt is answered, then
/// resumes.
pub(super) fn write_stdout(bytes: &[u8]) {
let _guard = super::prompts::PROMPT_LOCK.lock().unwrap_or_else(|e| e.into_inner());
#[cfg(test)]
print!("{}", String::from_utf8_lossy(bytes));
#[cfg(not(test))]

Loading…
Cancel
Save