From f6afb70b07e0e016dd9749a7b61dde9347b795ad Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sun, 27 Mar 2022 22:52:31 +0430 Subject: [PATCH] LibLine: Handle read events serially Previously LibLine accepted read callbacks while it was in the process of reading input, this wasn't an issue as no async code was being executed up until the Shell autocompletion came along. Simply defer input processing while processing input to avoid causing problems. Fixes #13280. --- Userland/Libraries/LibLine/Editor.cpp | 7 +++++++ Userland/Libraries/LibLine/Editor.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp index bbf6708839..35ac617042 100644 --- a/Userland/Libraries/LibLine/Editor.cpp +++ b/Userland/Libraries/LibLine/Editor.cpp @@ -791,6 +791,13 @@ void Editor::handle_interrupt_event() void Editor::handle_read_event() { + if (m_prohibit_input_processing) { + m_have_unprocessed_read_event = true; + return; + } + + auto prohibit_scope = prohibit_input(); + char keybuf[16]; ssize_t nread = 0; diff --git a/Userland/Libraries/LibLine/Editor.h b/Userland/Libraries/LibLine/Editor.h index 5215505a4e..bc835398e3 100644 --- a/Userland/Libraries/LibLine/Editor.h +++ b/Userland/Libraries/LibLine/Editor.h @@ -241,6 +241,20 @@ public: const Utf32View buffer_view() const { return { m_buffer.data(), m_buffer.size() }; } + auto prohibit_input() + { + auto previous_value = m_prohibit_input_processing; + m_prohibit_input_processing = true; + m_have_unprocessed_read_event = false; + return ScopeGuard { + [this, previous_value] { + m_prohibit_input_processing = previous_value; + if (!m_prohibit_input_processing && m_have_unprocessed_read_event) + handle_read_event(); + } + }; + } + private: explicit Editor(Configuration configuration = Configuration::from_config()); @@ -500,6 +514,8 @@ private: Vector m_signal_handlers; bool m_is_editing { false }; + bool m_prohibit_input_processing { false }; + bool m_have_unprocessed_read_event { false }; Configuration m_configuration; };