Kylin/Universal/IoContext.cpp
2024-11-10 18:02:28 +08:00

59 lines
1.7 KiB
C++

#include "IoContext.h"
#include <boost/asio/executor_work_guard.hpp>
#include <boost/scope_exit.hpp>
#include <boost/stacktrace.hpp>
IoContext::IoContext(int concurrency_hint)
: m_concurrency(concurrency_hint), m_ioContext(std::make_shared<boost::asio::io_context>(concurrency_hint)) {
}
IoContext::~IoContext() {
stop();
}
void IoContext::stop() {
m_guarder.reset();
m_ioContext->stop();
if (!m_asynchronous) {
for (auto &thread : m_threads) {
if (thread.joinable()) thread.join();
}
m_threads.clear();
}
}
void IoContext::run(bool asynchronous) {
using namespace boost::asio;
if (m_concurrency < 1) m_concurrency = 1;
m_asynchronous = asynchronous;
for (int i = 0; i < m_concurrency; i++) {
m_threads.push_back(std::thread(&IoContext::runIoContext, this));
}
m_guarder = std::make_unique<executor_work_guard<io_context::executor_type>>(m_ioContext->get_executor());
if (asynchronous) {
for (auto &thread : m_threads) {
if (thread.joinable()) thread.join();
}
m_threads.clear();
}
}
void IoContext::runIoContext() {
try {
m_ioContext->run();
} catch (const boost::log::system_error &error) {
LOG(error) << error.what();
} catch (const std::out_of_range &e) {
LOG(error) << e.what();
} catch (const boost::exception &e) {
LOG(error) << boost::diagnostic_information(e);
} catch (const std::exception &e) {
#if BOOST_VERSION < 108600
LOG(error) << e.what();
#else
boost::stacktrace::stacktrace trace = boost::stacktrace::stacktrace::from_current_exception();
LOG(error) << e.what() << ", trace:\n" << trace;
#endif
}
}