Skip to content

Fix stdin blocking issue in service stop spinner using libc::poll#27

Merged
pRizz merged 2 commits intomainfrom
claude/fix-cli-shutdown-terminal-QmeCg
Feb 6, 2026
Merged

Fix stdin blocking issue in service stop spinner using libc::poll#27
pRizz merged 2 commits intomainfrom
claude/fix-cli-shutdown-terminal-QmeCg

Conversation

@pRizz
Copy link
Owner

@pRizz pRizz commented Feb 6, 2026

Summary

Replace tokio's async stdin with a blocking task using libc::poll to fix a persistent blocking issue in the service stop spinner. The previous implementation using tokio::io::stdin() would hang indefinitely because tokio's internal blocking thread persists even after task abort, preventing graceful shutdown.

Changes

  • Add libc dependency (v0.2) to workspace and CLI package
  • Replace async stdin reader with spawn_blocking task that uses libc::poll
  • Implement cancellation flag using Arc<AtomicBool> instead of AbortHandle
  • Poll stdin with 100ms timeout to periodically check cancellation flag
  • Simplify return type from Result<std::io::Result<bool>> to bool
  • Update user_pressed_enter helper to match new return type

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Refactoring (no functional changes to public API)

Testing

Describe how you tested your changes:

  • Unit tests pass (just test-rust)
  • Linting passes (just lint)
  • Manual testing performed

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Related Issues

Fixes stdin blocking issue in service stop command that prevented graceful shutdown.

https://claude.ai/code/session_01MwaCtnDsCDV5cmwhX8LGFP

The stdin reader in stop_service_with_spinner used tokio::io::stdin()
which spawns an internal blocking thread. When the container stopped
gracefully (winning the select! race), aborting the tokio task did not
terminate the underlying OS thread blocked on read(), preventing the
process from exiting cleanly.

Replace with a libc::poll-based approach that checks a cancellation
AtomicBool every 100ms, allowing the blocking thread to exit promptly
when the stop completes.

https://claude.ai/code/session_01MwaCtnDsCDV5cmwhX8LGFP
Replace libc::poll-based stdin reader with a plain std::thread that
communicates through a tokio::sync::oneshot channel. A plain thread is
not part of tokio's blocking pool, so the runtime can shut down cleanly
even if the thread is still blocked on read_line — the OS terminates it
when the process exits.

This removes the libc dependency while keeping the same fix for the
terminal hang after graceful container shutdown.

https://claude.ai/code/session_01MwaCtnDsCDV5cmwhX8LGFP
@pRizz pRizz merged commit 774e717 into main Feb 6, 2026
10 checks passed
@pRizz pRizz deleted the claude/fix-cli-shutdown-terminal-QmeCg branch February 6, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants