mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:27:44 +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:
parent
47b6030347
commit
89877b3f40
2 changed files with 17 additions and 9 deletions
|
@ -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()) {
|
||||
Core::deferred_invoke([&connection, &cache_entry = *it->value, key = it->key, &cache] {
|
||||
connection->socket->set_notifications_enabled(false);
|
||||
// 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] {
|
||||
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 {
|
||||
|
|
|
@ -241,6 +241,7 @@ decltype(auto) get_or_create_connection(auto& cache, URL const& url, auto& job,
|
|||
return ReturnType { nullptr };
|
||||
}
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Immediately start request for url {} in {} - {}", url, &connection, connection.socket);
|
||||
Core::deferred_invoke([&connection, url, &job] {
|
||||
connection.has_started = true;
|
||||
connection.removal_timer->stop();
|
||||
connection.timer.start();
|
||||
|
@ -248,6 +249,7 @@ decltype(auto) get_or_create_connection(auto& cache, URL const& url, auto& job,
|
|||
connection.job_data = decltype(connection.job_data)::create(job);
|
||||
connection.socket->set_notifications_enabled(true);
|
||||
connection.job_data.start(*connection.socket);
|
||||
});
|
||||
} else {
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Enqueue request for URL {} in {} - {}", url, &connection, connection.socket);
|
||||
connection.request_queue.append(decltype(connection.job_data)::create(job));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue