IoEngine: explicitly join I/O threads

This commit is contained in:
Alexander A. Klimov 2019-02-15 15:43:58 +01:00
parent 493a97f4f3
commit 282f8fd173
2 changed files with 27 additions and 3 deletions

View File

@ -99,7 +99,7 @@ boost::asio::io_service& IoEngine::GetIoService()
return m_IoService;
}
IoEngine::IoEngine() : m_IoService(), m_KeepAlive(m_IoService), m_AlreadyExpiredTimer(m_IoService)
IoEngine::IoEngine() : m_IoService(), m_KeepAlive(m_IoService), m_Threads(decltype(m_Threads)::size_type(std::thread::hardware_concurrency())), m_AlreadyExpiredTimer(m_IoService)
{
m_AlreadyExpiredTimer.expires_at(boost::posix_time::neg_infin);
@ -111,8 +111,21 @@ IoEngine::IoEngine() : m_IoService(), m_KeepAlive(m_IoService), m_AlreadyExpired
m_CpuBoundSemaphore.store(concurrency - 1u);
}
for (auto i (std::thread::hardware_concurrency()); i; --i) {
std::thread(&IoEngine::RunEventLoop, this).detach();
for (auto& thread : m_Threads) {
thread = std::thread(&IoEngine::RunEventLoop, this);
}
}
IoEngine::~IoEngine()
{
for (auto& thread : m_Threads) {
m_IoService.post([]() {
throw TerminateIoThread();
});
}
for (auto& thread : m_Threads) {
thread.join();
}
}
@ -122,6 +135,8 @@ void IoEngine::RunEventLoop()
try {
m_IoService.run();
break;
} catch (const TerminateIoThread&) {
break;
} catch (const std::exception& e) {
Log(LogCritical, "IoEngine", "Exception during I/O operation!");

View File

@ -22,7 +22,10 @@
#include "base/lazy-init.hpp"
#include <atomic>
#include <exception>
#include <memory>
#include <thread>
#include <vector>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/spawn.hpp>
@ -82,6 +85,7 @@ public:
IoEngine(IoEngine&&) = delete;
IoEngine& operator=(const IoEngine&) = delete;
IoEngine& operator=(IoEngine&&) = delete;
~IoEngine();
static IoEngine& Get();
@ -96,8 +100,13 @@ private:
boost::asio::io_service m_IoService;
boost::asio::io_service::work m_KeepAlive;
std::vector<std::thread> m_Threads;
boost::asio::deadline_timer m_AlreadyExpiredTimer;
std::atomic_uint_fast32_t m_CpuBoundSemaphore;
};
class TerminateIoThread : public std::exception
{
};
#endif /* IO_ENGINE_H */