From 4d703b792c122bb32a4291694b7382c103c6073d Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 20 Oct 2022 17:13:18 +0200 Subject: [PATCH] Attempt to fix abort from parallel parsing (#42496) --- src/Common/ThreadPool.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Common/ThreadPool.h b/src/Common/ThreadPool.h index 76ada9e0d75..b3ab20ae592 100644 --- a/src/Common/ThreadPool.h +++ b/src/Common/ThreadPool.h @@ -178,7 +178,11 @@ public: func = std::forward(func), args = std::make_tuple(std::forward(args)...)]() mutable /// mutable is needed to destroy capture { - SCOPE_EXIT(state->event.set()); + SCOPE_EXIT( + { + state->finished = true; + state->event.set(); + }); state->thread_id = std::this_thread::get_id(); @@ -213,6 +217,17 @@ public: ~ThreadFromGlobalPoolImpl() { + /// The problem is that the our ThreadFromGlobalPool can be actually finished + /// before we try to join the thread or check whether it is joinable or not. + /// In some places we have code like: + /// if (thread->joinable()) + /// thread->join(); + /// Where join() won't be executed in case when we call it + /// from the same std::thread and it will end to std::abort(). + /// So we just do nothing in this case + if (state->finished) + return; + if (initialized()) abort(); } @@ -252,6 +267,9 @@ protected: /// The state used in this object and inside the thread job. Poco::Event event; + + /// To allow joining to the same std::thread after finishing + std::atomic finished{false}; }; std::shared_ptr state;