From b9b2274078b2e6ee677db1b423da35d54d6374ea Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 29 Aug 2023 07:42:09 -0400 Subject: [PATCH] Browser: Prevent moving a Database callback while it is executing All SQL callbacks here were already moving the to-be-executed callback out of its storage before executing it, except for on_next_result(). This makes on_next_result() do the same move to ensure we do not later attempt to move it while the callback is executing. --- Userland/Applications/Browser/Database.cpp | 35 +++++++++------------- Userland/Applications/Browser/Database.h | 4 +-- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/Userland/Applications/Browser/Database.cpp b/Userland/Applications/Browser/Database.cpp index 6931be0b281..532eafb183e 100644 --- a/Userland/Applications/Browser/Database.cpp +++ b/Userland/Applications/Browser/Database.cpp @@ -34,39 +34,32 @@ Database::Database(NonnullRefPtr sql_client, SQL::ConnectionID c if (result.has_results) return; - if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { - auto in_progress_statement = move(it->value); - m_pending_executions.remove(it); - - if (in_progress_statement.on_complete) - in_progress_statement.on_complete(); + if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) { + if (in_progress_statement->on_complete) + in_progress_statement->on_complete(); } }; m_sql_client->on_next_result = [this](auto result) { - if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { - if (it->value.on_result) - it->value.on_result(result.values); + if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) { + if (in_progress_statement->on_result) + in_progress_statement->on_result(result.values); + + m_pending_executions.set({ result.statement_id, result.execution_id }, in_progress_statement.release_value()); } }; m_sql_client->on_results_exhausted = [this](auto result) { - if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { - auto in_progress_statement = move(it->value); - m_pending_executions.remove(it); - - if (in_progress_statement.on_complete) - in_progress_statement.on_complete(); + if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) { + if (in_progress_statement->on_complete) + in_progress_statement->on_complete(); } }; m_sql_client->on_execution_error = [this](auto result) { - if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { - auto in_progress_statement = move(it->value); - m_pending_executions.remove(it); - - if (in_progress_statement.on_error) - in_progress_statement.on_error(result.error_message); + if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) { + if (in_progress_statement->on_error) + in_progress_statement->on_error(result.error_message); } }; } diff --git a/Userland/Applications/Browser/Database.h b/Userland/Applications/Browser/Database.h index d7a7b49599c..ee684e03b85 100644 --- a/Userland/Applications/Browser/Database.h +++ b/Userland/Applications/Browser/Database.h @@ -81,9 +81,9 @@ private: void execute_statement(SQL::StatementID statement_id, Vector placeholder_values, PendingExecution pending_execution); template - auto find_pending_execution(ResultData const& result_data) + auto take_pending_execution(ResultData const& result_data) { - return m_pending_executions.find({ result_data.statement_id, result_data.execution_id }); + return m_pending_executions.take({ result_data.statement_id, result_data.execution_id }); } NonnullRefPtr m_sql_client;