summaryrefslogtreecommitdiff
path: root/runtime/ops/tty.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-11-04 05:00:12 -0700
committerGitHub <noreply@github.com>2023-11-04 17:30:12 +0530
commit0b75a7169b2e123cac04e7ffcaf16a28eb356fd0 (patch)
tree117c69975e5942ae4deb462d1d3c1a0790b78c3c /runtime/ops/tty.rs
parent8acf059ac683ff13c6973914c57caa0ef07d6d9a (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.rs35
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);