1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:27:45 +00:00

RequestServer: Avoid race condition between cached request end/start

Prior to this commit, it was possible to get a socket stuck in a state
with enqueued entries, waiting for a nonexistent request to finish.
This state could be entered by issuing a request immediately after the
completion of another one, and before deferred_invoke execution in the
event loop.

This commit closes this hole by making sure the socket is never in a
state where it can queue requests without an active job.
This commit is contained in:
Ali Mohammad Pur 2023-12-15 06:34:34 +03:30 committed by Andreas Kling
parent 47b6030347
commit 89877b3f40
2 changed files with 17 additions and 9 deletions

View file

@ -38,9 +38,15 @@ void request_did_finish(URL const& url, Core::Socket const* socket)
auto& connection = *connection_it;
if (connection->request_queue.is_empty()) {
// Immediately mark the connection as finished, as new jobs will never be run if they are queued
// before the deferred_invoke() below runs otherwise.
connection->has_started = false;
connection->socket->set_notifications_enabled(false);
Core::deferred_invoke([&connection, &cache_entry = *it->value, key = it->key, &cache] {
connection->socket->set_notifications_enabled(false);
connection->has_started = false;
if (connection->has_started)
return;
connection->current_url = {};
connection->job_data = {};
connection->removal_timer->on_timeout = [ptr = connection.ptr(), &cache_entry, key = move(key), &cache]() mutable {