From 8031fa3bdb8a856ff1f90996386f285099f743c1 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 12 May 2019 12:33:13 -0700 Subject: [PATCH] Stop using atomic types for non-primitives atomic requires linking libatomic on some platforms which is annoying. Remove the one use. Fixes #5865 --- src/common.cpp | 40 +++++++++++++++++++++++++--------------- src/common.h | 1 + 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index 29a6a17fc..d1f8662c1 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -99,7 +99,7 @@ static relaxed_atomic_t initial_fg_process_group{-1}; /// This struct maintains the current state of the terminal size. It is updated on demand after /// receiving a SIGWINCH. Use common_get_width()/common_get_height() to read it lazily. static constexpr struct winsize k_invalid_termsize = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; -static relaxed_atomic_t s_termsize(k_invalid_termsize); +static owning_lock s_termsize{k_invalid_termsize}; static relaxed_atomic_bool_t s_termsize_valid{false}; @@ -1745,9 +1745,8 @@ bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t e void invalidate_termsize(bool invalidate_vars) { s_termsize_valid = false; if (invalidate_vars) { - struct winsize termsize = s_termsize; - termsize.ws_col = termsize.ws_row = USHRT_MAX; - termsize = s_termsize; + auto termsize = s_termsize.acquire(); + termsize->ws_col = termsize->ws_row = USHRT_MAX; } } @@ -1810,27 +1809,38 @@ static void export_new_termsize(struct winsize *new_termsize, env_stack_t &vars) #endif } -/// Updates termsize as needed, and returns a copy of the winsize. -struct winsize get_current_winsize() { - struct winsize termsize = s_termsize; - if (s_termsize_valid) return termsize; +/// Get the current termsize, lazily computing it. Return by reference if it changed. +static struct winsize get_current_winsize_prim(bool *changed, const environment_t &vars) { + auto termsize = s_termsize.acquire(); + if (s_termsize_valid) return *termsize; struct winsize new_termsize = {0, 0, 0, 0}; #ifdef HAVE_WINSIZE errno = 0; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &new_termsize) != -1 && - new_termsize.ws_col == termsize.ws_col && new_termsize.ws_row == termsize.ws_row) { + new_termsize.ws_col == termsize->ws_col && new_termsize.ws_row == termsize->ws_row) { s_termsize_valid = true; - return termsize; + return *termsize; } #endif - auto &vars = env_stack_t::globals(); validate_new_termsize(&new_termsize, vars); - export_new_termsize(&new_termsize, vars); - termsize.ws_col = new_termsize.ws_col; - termsize.ws_row = new_termsize.ws_row; - s_termsize = termsize; + termsize->ws_col = new_termsize.ws_col; + termsize->ws_row = new_termsize.ws_row; + *changed = true; s_termsize_valid = true; + return *termsize; +} + +/// Updates termsize as needed, and returns a copy of the winsize. +struct winsize get_current_winsize() { + bool changed = false; + auto &vars = env_stack_t::globals(); + struct winsize termsize = get_current_winsize_prim(&changed, vars); + if (changed) { + // TODO: this may call us reentrantly through the environment dispatch mechanism. We need to + // rationalize this. + export_new_termsize(&termsize, vars); + } return termsize; } diff --git a/src/common.h b/src/common.h index db12471ea..4ca30c9db 100644 --- a/src/common.h +++ b/src/common.h @@ -649,6 +649,7 @@ class owning_lock { public: owning_lock(Data &&d) : data(std::move(d)) {} + owning_lock(const Data &d) : data(d) {} owning_lock() : data() {} acquired_lock acquire() { return {lock, &data}; }