#1039

How to temporarily lock EventStream polling

Openhasezoeyopened 8mo ago

Is your feature request related to a problem? Please describe. We have a TUI application which make use of crossterm's EventStream as the input listener, but we also want to use other libraries like viuer to display images, which requires sending & receiving ANSI sequences in viuer. viuer currently handles that via the console crate, but i have noticed that when both crossterm's EventStream and a viuer sequence read is active, the sequence read may be incomplete and has been eaten by the EventStream. I have also not found any locking that i could do for crossterm, and it does not seem to respect std::io::Stdin::lock.

I also dont think just switching viuer over to use crossterm's polling will fully resolve this race condition.

Describe the solution you'd like Either respect std::io::Stdin being locked (via ::lock), or an alternative for crossterm to lock it's polling.

Describe alternatives you've considered if any The only alternatives i can currently think of:

  • not using viuer
  • accepting that the TUI freezes due to viuer being in a infinite loop waiting for the response
  • somehow shutting down the EventStream and then starting it back up before & after each viuer call
  • switching viuer to use crossterm's event polling and crossterm providing a way to send and read arbitrary escape sequences (like sending kitty image protocol data, along with a DSR and waiting for the DSR)

Additional context Note that crossterm's EventStream is used trough tui-realm. This issue originally came up with https://github.com/tramhao/termusic/pull/654#issuecomment-3998329190, and i tried following where the issue comes from with further comments.

I have already skimmed through https://github.com/crossterm-rs/crossterm/issues/199 and https://github.com/crossterm-rs/crossterm-input/pull/9 which seemed related.


I may also complete misunderstand the problem i have at hand.

Activity

5
gavincrawford5mo ago

I haven't looked very far into this issue yet, but I'm just wondering if manually running poll could allow you to skirt around the issue? It might be possible to only poll when you want this library to handle events, and use the viuer sequence read otherwise. I'm not sure if this would interfere, but it could be worth a shot :)

gavincrawford5mo ago

I haven't looked very far into this issue yet, but I'm just wondering if manually running poll could allow you to skirt around the issue? It might be possible to only poll when you want this library to handle events, and use the viuer sequence read otherwise. I'm not sure if this would interfere, but it could be worth a shot :)

hasezoey5mo ago

I haven't looked very far into this issue yet, but I'm just wondering if manually running poll could allow you to skirt around the issue?

Now that i look at the current implementation of EventStream again, it might be possible to do this, due to the thread spawned by EventStream only polling if it has gotten a request from the EventStream.

For context, my previous understanding was that EventStream started a new thread (which it still does) which actually polls synchronously eagerly. Though having looked at the implementation again, as stated above, it seems to only poll on request.

hasezoey5mo ago

I haven't looked very far into this issue yet, but I'm just wondering if manually running poll could allow you to skirt around the issue?

Now that i look at the current implementation of EventStream again, it might be possible to do this, due to the thread spawned by EventStream only polling if it has gotten a request from the EventStream.

For context, my previous understanding was that EventStream started a new thread (which it still does) which actually polls synchronously eagerly. Though having looked at the implementation again, as stated above, it seems to only poll on request.

hiSandog3mo ago

Stdin locking cannot coordinate a background event reader reliably; the process needs a single owner that multiplexes user events and terminal query responses. A pause/transaction guard on EventStream could stop issuing new poll requests, wait for any in-flight read to finish, let the caller send/read a bounded response, then resume without losing buffered events. PTY tests should interleave keypresses with DSR/Kitty responses and verify cancellation or timeout always releases the guard.