LibLine: Stop registering the Notifier as a child Object

We're already keeping it alive via `m_notifier`.
This makes the event loop quitting logic simpler by making less
deferred calls and removes a race condition where the notifier would be
deleted before the second deferred_invoke() would be invoked, leading
to a nullptr dereference.
Fixes #7822.
This commit is contained in:
Ali Mohammad Pur 2021-06-06 23:15:51 +04:30 committed by Ali Mohammad Pur
parent 73ff571d24
commit d8c5eeceab
Notes: sideshowbarker 2024-07-18 12:44:05 +09:00

View file

@ -588,11 +588,8 @@ void Editor::interrupted()
m_is_editing = false; m_is_editing = false;
restore(); restore();
m_notifier->set_enabled(false); m_notifier->set_enabled(false);
deferred_invoke([this](auto&) {
remove_child(*m_notifier);
m_notifier = nullptr; m_notifier = nullptr;
Core::EventLoop::current().quit(Retry); Core::EventLoop::current().quit(Retry);
});
} }
void Editor::resized() void Editor::resized()
@ -626,15 +623,14 @@ void Editor::really_quit_event_loop()
m_returned_line = string; m_returned_line = string;
m_notifier->set_enabled(false); m_notifier->set_enabled(false);
deferred_invoke([this](auto&) {
remove_child(*m_notifier);
m_notifier = nullptr; m_notifier = nullptr;
Core::EventLoop::current().quit(Exit); Core::EventLoop::current().quit(Exit);
});
} }
auto Editor::get_line(const String& prompt) -> Result<String, Editor::Error> auto Editor::get_line(const String& prompt) -> Result<String, Editor::Error>
{ {
OwnPtr<Core::EventLoop> event_loop;
do {
initialize(); initialize();
m_is_editing = true; m_is_editing = true;
@ -691,17 +687,17 @@ auto Editor::get_line(const String& prompt) -> Result<String, Editor::Error>
refresh_display(); refresh_display();
Core::EventLoop loop; if (!event_loop)
event_loop = make<Core::EventLoop>();
if (!m_notifier) {
m_notifier = Core::Notifier::construct(STDIN_FILENO, Core::Notifier::Read); m_notifier = Core::Notifier::construct(STDIN_FILENO, Core::Notifier::Read);
add_child(*m_notifier); }
m_notifier->on_ready_to_read = [&] { try_update_once(); }; m_notifier->on_ready_to_read = [&] { try_update_once(); };
if (!m_incomplete_data.is_empty()) if (!m_incomplete_data.is_empty())
deferred_invoke([&](auto&) { try_update_once(); }); deferred_invoke([&](auto&) { try_update_once(); });
} while (event_loop->exec() == Retry);
if (loop.exec() == Retry)
return get_line(prompt);
return m_input_error.has_value() ? Result<String, Editor::Error> { m_input_error.value() } : Result<String, Editor::Error> { m_returned_line }; return m_input_error.has_value() ? Result<String, Editor::Error> { m_input_error.value() } : Result<String, Editor::Error> { m_returned_line };
} }