浏览代码

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.
Ali Mohammad Pur 3 年之前
父节点
当前提交
f6afb70b07
共有 2 个文件被更改,包括 23 次插入0 次删除
  1. 7 0
      Userland/Libraries/LibLine/Editor.cpp
  2. 16 0
      Userland/Libraries/LibLine/Editor.h

+ 7 - 0
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;
 

+ 16 - 0
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<int, 2> m_signal_handlers;
 
     bool m_is_editing { false };
+    bool m_prohibit_input_processing { false };
+    bool m_have_unprocessed_read_event { false };
 
     Configuration m_configuration;
 };