RequestServer: Manually destroy the thread pool before exit

The ThreadPool destructor joins all threads. Therefore, this
destructor should be called before the destructors of all static
variables that are used in those threads.
This commit is contained in:
Sönke Holz authored and Ali Mohammad Pur committed 2025-08-14 17:41:06 +02:00
1 parent 30e5391c99
commit f5cbee83cc
3 files changed
+20 -7

No files matched your search

@@ -47,12 +47,7 @@ struct ThreadPoolEntry {
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
static IDAllocator s_client_ids;
static ThreadPipeFds s_thread_pipe_fds {};
static Threading::ThreadPool<ThreadPoolEntry, ConnectionFromClient::Looper> s_thread_pool {
[](ThreadPoolEntry entry) {
entry.client->worker_do_work(move(entry.work));
},
{}, s_thread_pipe_fds.fds[0]
};
static OwnPtr<Threading::ThreadPool<ThreadPoolEntry, ConnectionFromClient::Looper>> s_thread_pool;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionFromClient<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), s_client_ids.allocate())
@@ -245,7 +240,14 @@ Messages::RequestServer::ConnectNewClientResponse ConnectionFromClient::connect_
void ConnectionFromClient::enqueue(Work work)
{
s_thread_pool.submit({ *this, move(work) });
if (!s_thread_pool) {
s_thread_pool = adopt_own(*new (nothrow) Threading::ThreadPool<ThreadPoolEntry, ConnectionFromClient::Looper>(
[](ThreadPoolEntry entry) {
entry.client->worker_do_work(move(entry.work));
},
{}, s_thread_pipe_fds.fds[0]));
}
s_thread_pool->submit({ *this, move(work) });
auto nwritten = write(s_thread_pipe_fds[1], "x", 1); // notify the worker threads
if (nwritten < 0) {
VERIFY_NOT_REACHED();
@@ -429,4 +431,9 @@ void ConnectionFromClient::dump_connection_info()
ConnectionCache::dump_jobs();
}
void ConnectionFromClient::destroy_thread_pool()
{
s_thread_pool.clear();
}
}
@@ -32,6 +32,8 @@ public:
void did_progress_request(Badge<Request>, Request&);
void did_request_certificates(Badge<Request>, Request&);
static void destroy_thread_pool();
template<typename Pool>
struct Looper : public Threading::ThreadPoolLooper<Pool> {
Looper(int pipe_fd)
+4
View File
@@ -50,6 +50,10 @@ ErrorOr<int> serenity_main(Main::Arguments)
RequestServer::HttpProtocol::install();
RequestServer::HttpsProtocol::install();
ScopeGuard destroy_thread_pool_on_exit = [] {
RequestServer::ConnectionFromClient::destroy_thread_pool();
};
auto client = TRY(IPC::take_over_accepted_client_from_system_server<RequestServer::ConnectionFromClient>());
return event_loop.exec();