1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 23:57:34 +00:00

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.
This commit is contained in:
Timothy Flynn 2023-08-29 07:42:09 -04:00 committed by Andreas Kling
parent fab4d543f6
commit b9b2274078
2 changed files with 16 additions and 23 deletions

View file

@ -34,39 +34,32 @@ Database::Database(NonnullRefPtr<SQL::SQLClient> sql_client, SQL::ConnectionID c
if (result.has_results) if (result.has_results)
return; return;
if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) {
auto in_progress_statement = move(it->value); if (in_progress_statement->on_complete)
m_pending_executions.remove(it); in_progress_statement->on_complete();
if (in_progress_statement.on_complete)
in_progress_statement.on_complete();
} }
}; };
m_sql_client->on_next_result = [this](auto result) { m_sql_client->on_next_result = [this](auto result) {
if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) {
if (it->value.on_result) if (in_progress_statement->on_result)
it->value.on_result(result.values); 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) { m_sql_client->on_results_exhausted = [this](auto result) {
if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) {
auto in_progress_statement = move(it->value); if (in_progress_statement->on_complete)
m_pending_executions.remove(it); in_progress_statement->on_complete();
if (in_progress_statement.on_complete)
in_progress_statement.on_complete();
} }
}; };
m_sql_client->on_execution_error = [this](auto result) { m_sql_client->on_execution_error = [this](auto result) {
if (auto it = find_pending_execution(result); it != m_pending_executions.end()) { if (auto in_progress_statement = take_pending_execution(result); in_progress_statement.has_value()) {
auto in_progress_statement = move(it->value); if (in_progress_statement->on_error)
m_pending_executions.remove(it); in_progress_statement->on_error(result.error_message);
if (in_progress_statement.on_error)
in_progress_statement.on_error(result.error_message);
} }
}; };
} }

View file

@ -81,9 +81,9 @@ private:
void execute_statement(SQL::StatementID statement_id, Vector<SQL::Value> placeholder_values, PendingExecution pending_execution); void execute_statement(SQL::StatementID statement_id, Vector<SQL::Value> placeholder_values, PendingExecution pending_execution);
template<typename ResultData> template<typename ResultData>
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<SQL::SQLClient> m_sql_client; NonnullRefPtr<SQL::SQLClient> m_sql_client;