RequestServer: Make the ThreadPool global

Previously we made one thread pool per ipc client, which is excessive
and can eat up all the available fds very fast.
Fixes #760.
This commit is contained in:
Ali Mohammad Pur 2024-07-22 22:52:21 +02:00 committed by Andreas Kling
commit 18499c4eac
Notes: github-actions[bot] 2024-07-23 06:57:54 +00:00
2 changed files with 35 additions and 28 deletions

View file

@ -21,12 +21,27 @@
namespace RequestServer {
template<typename Pool>
struct Looper : public Threading::ThreadPoolLooper<Pool> {
IterationDecision next(Pool& pool, bool wait);
Core::EventLoop event_loop;
};
struct ThreadPoolEntry {
NonnullRefPtr<ConnectionFromClient> client;
ConnectionFromClient::Work work;
};
static Threading::ThreadPool<ThreadPoolEntry, Looper> s_thread_pool {
[](ThreadPoolEntry entry) {
entry.client->worker_do_work(move(entry.work));
}
};
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
static IDAllocator s_client_ids;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionFromClient<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), s_client_ids.allocate())
, m_thread_pool([this](Work work) { worker_do_work(move(work)); })
{
s_connections.set(client_id(), *this);
}
@ -74,7 +89,7 @@ private:
};
template<typename Pool>
IterationDecision ConnectionFromClient::Looper<Pool>::next(Pool& pool, bool wait)
IterationDecision Looper<Pool>::next(Pool& pool, bool wait)
{
bool should_exit = false;
auto timer = Core::Timer::create_repeating(100, [&] {
@ -187,7 +202,7 @@ Messages::RequestServer::ConnectNewClientResponse ConnectionFromClient::connect_
void ConnectionFromClient::enqueue(Work work)
{
m_thread_pool.submit(move(work));
s_thread_pool.submit({ *this, move(work) });
}
Messages::RequestServer::IsSupportedProtocolResponse ConnectionFromClient::is_supported_protocol(ByteString const& protocol)

View file

@ -32,6 +32,23 @@ public:
void did_progress_request(Badge<Request>, Request&);
void did_request_certificates(Badge<Request>, Request&);
struct StartRequest {
i32 request_id;
ByteString method;
URL::URL url;
HTTP::HeaderMap request_headers;
ByteBuffer request_body;
Core::ProxyData proxy_data;
};
struct EnsureConnection {
URL::URL url;
CacheLevel cache_level;
};
using Work = Variant<StartRequest, EnsureConnection, Empty>;
void worker_do_work(Work);
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
@ -49,36 +66,11 @@ private:
virtual void websocket_close(i32, u16, ByteString const&) override;
virtual Messages::RequestServer::WebsocketSetCertificateResponse websocket_set_certificate(i32, ByteString const&, ByteString const&) override;
struct StartRequest {
i32 request_id;
ByteString method;
URL::URL url;
HTTP::HeaderMap request_headers;
ByteBuffer request_body;
Core::ProxyData proxy_data;
};
struct EnsureConnection {
URL::URL url;
CacheLevel cache_level;
};
using Work = Variant<StartRequest, EnsureConnection, Empty>;
void worker_do_work(Work);
Threading::MutexProtected<HashMap<i32, OwnPtr<Request>>> m_requests;
HashMap<i32, RefPtr<WebSocket::WebSocket>> m_websockets;
void enqueue(Work);
template<typename Pool>
struct Looper : public Threading::ThreadPoolLooper<Pool> {
IterationDecision next(Pool& pool, bool wait);
Core::EventLoop event_loop;
};
Threading::ThreadPool<Work, Looper> m_thread_pool;
Threading::Mutex m_ipc_mutex;
};