Created
May 25, 2020 21:21
Revisions
-
dsanson created this gist
May 25, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,87 @@ --- a/src/common.cpp +++ b/src/common.cpp @@ -103,7 +103,7 @@ static relaxed_atomic_t<pid_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 owning_lock<struct winsize> s_termsize{k_invalid_termsize}; +static relaxed_atomic_t<struct winsize> s_termsize(k_invalid_termsize); static relaxed_atomic_bool_t s_termsize_valid{false}; @@ -1749,8 +1749,9 @@ 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) { - auto termsize = s_termsize.acquire(); - termsize->ws_col = termsize->ws_row = USHRT_MAX; + struct winsize termsize = s_termsize; + termsize.ws_col = termsize.ws_row = USHRT_MAX; + termsize = s_termsize; } } @@ -1818,42 +1819,27 @@ static void export_new_termsize(struct winsize *new_termsize, env_stack_t &vars) #endif } -/// 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; +/// 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; 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); - termsize->ws_col = new_termsize.ws_col; - termsize->ws_row = new_termsize.ws_row; - *changed = true; + export_new_termsize(&new_termsize, vars); + termsize.ws_col = new_termsize.ws_col; + termsize.ws_row = new_termsize.ws_row; + s_termsize = termsize; 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); - // Hack: due to the dispatch the termsize may have just become invalid. Stomp it back to - // valid. What a mess. - *s_termsize.acquire() = termsize; - s_termsize_valid = true; - } return termsize; } --- a/src/common.h +++ b/src/common.h @@ -494,7 +494,6 @@ class owning_lock { public: owning_lock(Data &&d) : data(std::move(d)) {} - owning_lock(const Data &d) : data(d) {} owning_lock() : data() {} acquired_lock<Data> acquire() { return {lock, &data}; }