Make the input_common lookahead main-thread only

This commit is contained in:
ridiculousfish 2019-05-04 17:32:40 -07:00
parent 9018a7d5ee
commit 1e171140d5
2 changed files with 40 additions and 29 deletions

View file

@ -34,6 +34,11 @@ class mainthread_t : detail::fixed_t {
mainthread_t(T value) : value_(std::move(value)) {} mainthread_t(T value) : value_(std::move(value)) {}
mainthread_t() = default; mainthread_t() = default;
T *operator->() {
ASSERT_IS_MAIN_THREAD();
return &value_;
}
operator T &() { operator T &() {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
return value_; return value_;

View file

@ -23,6 +23,7 @@
#include "env.h" #include "env.h"
#include "env_universal_common.h" #include "env_universal_common.h"
#include "fallback.h" // IWYU pragma: keep #include "fallback.h" // IWYU pragma: keep
#include "global_safety.h"
#include "input_common.h" #include "input_common.h"
#include "iothread.h" #include "iothread.h"
#include "wutil.h" #include "wutil.h"
@ -33,31 +34,35 @@
#define WAIT_ON_ESCAPE_DEFAULT 30 #define WAIT_ON_ESCAPE_DEFAULT 30
static int wait_on_escape_ms = WAIT_ON_ESCAPE_DEFAULT; static int wait_on_escape_ms = WAIT_ON_ESCAPE_DEFAULT;
/// Events which have been read and returned by the sequence matching code. struct input_lookahead_t {
static std::deque<char_event_t> lookahead_list; /// Events which have been read and returned by the sequence matching code.
std::deque<char_event_t> lookahead_list;
static bool has_lookahead() { return !lookahead_list.empty(); } bool has_lookahead() const { return !lookahead_list.empty(); }
static char_event_t lookahead_pop() { char_event_t pop() {
auto result = lookahead_list.front(); auto result = lookahead_list.front();
lookahead_list.pop_front(); lookahead_list.pop_front();
return result; return result;
}
/// \return the next lookahead char, or none if none. Discards timeouts.
static maybe_t<char_event_t> lookahead_pop_evt() {
while (has_lookahead()) {
auto evt = lookahead_pop();
if (! evt.is_timeout()) {
return evt;
}
} }
return none();
}
static void lookahead_push_back(char_event_t c) { lookahead_list.push_back(c); } /// \return the next lookahead char, or none if none. Discards timeouts.
maybe_t<char_event_t> pop_evt() {
while (has_lookahead()) {
auto evt = pop();
if (!evt.is_timeout()) {
return evt;
}
}
return none();
}
static void lookahead_push_front(char_event_t c) { lookahead_list.push_front(c); } void push_back(char_event_t c) { lookahead_list.push_back(c); }
void push_front(char_event_t c) { lookahead_list.push_front(c); }
};
static mainthread_t<input_lookahead_t> s_lookahead;
/// Callback function for handling interrupts on reading. /// Callback function for handling interrupts on reading.
static interrupt_func_t interrupt_handler; static interrupt_func_t interrupt_handler;
@ -105,7 +110,7 @@ static char_event_t readb() {
if (interrupt_handler) { if (interrupt_handler) {
if (auto interrupt_evt = interrupt_handler()) { if (auto interrupt_evt = interrupt_handler()) {
return *interrupt_evt; return *interrupt_evt;
} else if (auto mc = lookahead_pop_evt()) { } else if (auto mc = s_lookahead->pop_evt()) {
return *mc; return *mc;
} }
} }
@ -123,7 +128,7 @@ static char_event_t readb() {
if (barrier_from_poll || barrier_from_readability) { if (barrier_from_poll || barrier_from_readability) {
if (env_universal_barrier()) { if (env_universal_barrier()) {
// A variable change may have triggered a repaint, etc. // A variable change may have triggered a repaint, etc.
if (auto mc = lookahead_pop_evt()) { if (auto mc = s_lookahead->pop_evt()) {
return *mc; return *mc;
} }
} }
@ -131,7 +136,7 @@ static char_event_t readb() {
if (ioport > 0 && FD_ISSET(ioport, &fdset)) { if (ioport > 0 && FD_ISSET(ioport, &fdset)) {
iothread_service_completion(); iothread_service_completion();
if (auto mc = lookahead_pop_evt()) { if (auto mc = s_lookahead->pop_evt()) {
return *mc; return *mc;
} }
} }
@ -171,7 +176,8 @@ void update_wait_on_escape_ms(const environment_t &vars) {
} }
char_event_t input_common_readch() { char_event_t input_common_readch() {
if (auto mc = lookahead_pop_evt()) { ASSERT_IS_MAIN_THREAD();
if (auto mc = s_lookahead->pop_evt()) {
return *mc; return *mc;
} }
wchar_t res; wchar_t res;
@ -209,8 +215,8 @@ char_event_t input_common_readch() {
char_event_t input_common_readch_timed(bool dequeue_timeouts) { char_event_t input_common_readch_timed(bool dequeue_timeouts) {
char_event_t result{char_event_type_t::timeout}; char_event_t result{char_event_type_t::timeout};
if (has_lookahead()) { if (s_lookahead->has_lookahead()) {
result = lookahead_pop(); result = s_lookahead->pop();
} else { } else {
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
@ -222,12 +228,12 @@ char_event_t input_common_readch_timed(bool dequeue_timeouts) {
} }
// If we got a timeout, either through dequeuing or creating, ensure it stays on the queue. // If we got a timeout, either through dequeuing or creating, ensure it stays on the queue.
if (result.is_timeout()) { if (result.is_timeout()) {
if (!dequeue_timeouts) lookahead_push_front(char_event_type_t::timeout); if (!dequeue_timeouts) s_lookahead->push_front(char_event_type_t::timeout);
return char_event_type_t::timeout; return char_event_type_t::timeout;
} }
return result; return result;
} }
void input_common_queue_ch(char_event_t ch) { lookahead_push_back(ch); } void input_common_queue_ch(char_event_t ch) { s_lookahead->push_back(ch); }
void input_common_next_ch(char_event_t ch) { lookahead_push_front(ch); } void input_common_next_ch(char_event_t ch) { s_lookahead->push_front(ch); }