diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-11-04 05:00:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-04 17:30:12 +0530 |
commit | 0b75a7169b2e123cac04e7ffcaf16a28eb356fd0 (patch) | |
tree | 117c69975e5942ae4deb462d1d3c1a0790b78c3c /runtime/ops/tty.rs | |
parent | 8acf059ac683ff13c6973914c57caa0ef07d6d9a (diff) |
perf: lazy `atexit` setup (#21053)
`libc::atexit` incurrs 2% dyld cost at startup on macOS. This PR moves
the setup to when the tty mode is changed using op_stdin_set_raw.
Diffstat (limited to 'runtime/ops/tty.rs')
-rw-r--r-- | runtime/ops/tty.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs index bf85c757e..477af9741 100644 --- a/runtime/ops/tty.rs +++ b/runtime/ops/tty.rs @@ -118,6 +118,41 @@ fn op_stdin_set_raw( } #[cfg(unix)] { + fn prepare_stdio() { + // SAFETY: Save current state of stdio and restore it when we exit. + unsafe { + use libc::atexit; + use libc::tcgetattr; + use libc::tcsetattr; + use libc::termios; + use once_cell::sync::OnceCell; + + // Only save original state once. + static ORIG_TERMIOS: OnceCell<Option<termios>> = OnceCell::new(); + ORIG_TERMIOS.get_or_init(|| { + let mut termios = std::mem::zeroed::<termios>(); + if tcgetattr(libc::STDIN_FILENO, &mut termios) == 0 { + extern "C" fn reset_stdio() { + // SAFETY: Reset the stdio state. + unsafe { + tcsetattr( + libc::STDIN_FILENO, + 0, + &ORIG_TERMIOS.get().unwrap().unwrap(), + ) + }; + } + + atexit(reset_stdio); + return Some(termios); + } + + None + }); + } + } + + prepare_stdio(); let tty_mode_store = state.borrow::<TtyModeStore>().clone(); let previous_mode = tty_mode_store.get(rid); |