mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
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:
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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user