Rework how screen size is tracked

The screen size is fetched after a SIGWINCH is delivered. The current
implementation has two issues:

* It calls ioctl() from the SIGWINCH signal handler, despite ioctl() not
  being a function that is known to be safe to call.
* It's not thread-safe.

Signals can be delivered on arbitrary threads, so we don't know if it's
actually safe to be modifying the cached winsize in response to a
signal. It's also plausible that the winsize may be requested from a
background thread.

To solve the first issue, we twiddle a volatile boolean flag in the
signal handler and defer the ioctl() call until we actually request the
screen size.

To solve the second issue, we introduce a pthread rwlock around the
cached winsize. A rwlock is used because it can be expected that there
are likely to be far more window size reads than window size writes. If
we were using C++11 we could probably get away with atomics, but since
we don't have that (or boost), a rwlock should suffice.

Fixes #1613.
This commit is contained in:
Kevin Ballard
2014-08-24 00:59:03 -07:00
parent 24ac7d2698
commit cc52a59e1a
3 changed files with 159 additions and 19 deletions

View File

@@ -67,9 +67,6 @@ void function_autoload_t::command_removed(const wcstring &cmd)
function_remove_ignore_autoload(cmd);
}
/* Helper macro for vomiting */
#define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { int err = errno; fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", #a, __LINE__, __FILE__, err, strerror(err)); abort(); }} while (0)
/**
Kludgy flag set by the load function in order to tell function_add
that the function being defined is autoloaded. There should be a