Skip to content

Commit

Permalink
create threads out of the lock
Browse files Browse the repository at this point in the history
  • Loading branch information
filimonov committed Feb 6, 2024
1 parent d273117 commit 5cee6ef
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions src/Common/ThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <Common/noexcept_scope.h>

#include <cassert>
#include <future>
#include <type_traits>

#include <Poco/Util/Application.h>
Expand Down Expand Up @@ -225,27 +226,37 @@ ReturnType ThreadPoolImpl<Thread>::scheduleImpl(Job job, Priority priority, std:
{
try
{
threads.emplace_front();
}
catch (...)
{
/// Most likely this is a std::bad_alloc exception
return on_error("cannot allocate thread slot");
}
std::promise<typename std::list<Thread>::iterator> promise_thread_it;
std::shared_future<typename std::list<Thread>::iterator> future_thread_id = promise_thread_it.get_future().share();
lock.unlock();

try
{
Stopwatch watch2;
threads.front() = Thread([this, it = threads.begin()] { worker(it); });
/// we use future here for 2 reasons:
/// 1) just passing a ref to list iterator after adding the thread to the list
/// 2) hold the thread work until the thread is added to the list, otherwise
/// is can get the lock faster and then can wait for a cond_variable forever
auto thread = Thread([this, ft = std::move(future_thread_id)] mutable
{
auto thread_it = ft.get();
worker(thread_it);
});
ProfileEvents::increment(
std::is_same_v<Thread, std::thread> ? ProfileEvents::GlobalThreadPoolThreadCreationMicroseconds : ProfileEvents::LocalThreadPoolThreadCreationMicroseconds,
watch2.elapsedMicroseconds());
lock.lock();
ProfileEvents::increment(
std::is_same_v<Thread, std::thread> ? ProfileEvents::GlobalThreadPoolExpansions : ProfileEvents::LocalThreadPoolExpansions);
threads.push_front(std::move(thread));
promise_thread_it.set_value(threads.begin());
}
catch (const std::exception & e)
{
lock.lock();
return on_error(fmt::format("cannot start thread: {}", e.what()));
}
catch (...)
{
threads.pop_front();
lock.lock();
return on_error("cannot allocate thread");
}
}
Expand Down

0 comments on commit 5cee6ef

Please sign in to comment.