20 #include <condition_variable>
27 namespace concurrency {
31 std::shared_ptr<IoContext>
ioc_;
36 std::condition_variable
cv_;
41 explicit Impl(std::shared_ptr<IoContext> external_context) :
owns_context_(false),
ioc_(std::move(external_context)) {
63 std::lock_guard<std::mutex> lock(
mutex_);
72 if (
io_thread_.get_id() != std::this_thread::get_id()) {
75 UNILINK_LOG_ERROR(
"io_context_manager",
"stop",
"Cannot join IoContext thread from within itself.");
83 if (worker.joinable()) {
91 std::lock_guard<std::mutex> lock(
mutex_);
93 if (!worker.joinable() && !
io_thread_.joinable()) {
104 : impl_(std::make_unique<
Impl>(std::move(external_context))) {}
116 std::lock_guard<std::mutex> lock(impl_->mutex_);
118 impl_->ioc_ = std::make_shared<IoContext>();
119 impl_->owns_context_ =
true;
125 std::shared_ptr<IoContext> context;
127 std::unique_lock<std::mutex> lock(impl_->mutex_);
129 if (!impl_->owns_context_ && impl_->ioc_) {
130 if (impl_->ioc_->stopped()) {
136 impl_->cv_.wait(lock, [
this] {
return !impl_->stopping_; });
138 if (impl_->running_)
return;
140 if (impl_->io_thread_.joinable() && impl_->io_thread_.get_id() == std::this_thread::get_id()) {
141 UNILINK_LOG_ERROR(
"io_context_manager",
"start",
"Cannot restart from within its own thread.");
146 impl_->ioc_ = std::make_shared<IoContext>();
147 impl_->owns_context_ =
true;
150 if (impl_->ioc_->stopped()) {
151 impl_->ioc_->restart();
153 impl_->work_guard_ = std::make_unique<WorkGuard>(impl_->ioc_->get_executor());
154 context = impl_->ioc_;
156 if (impl_->io_thread_.joinable()) {
157 impl_->io_thread_.join();
160 impl_->io_thread_ = std::thread([
this, context]() {
163 }
catch (
const std::exception& e) {
164 UNILINK_LOG_ERROR(
"io_context_manager",
"run",
"Thread error: " + std::string(e.what()));
167 impl_->running_.store(
false);
169 impl_->running_.store(
true);
178 return std::make_unique<IoContext>();
std::unique_ptr< IoContext > create_independent_context()
IoContext & get_context()
boost::asio::io_context IoContext
IoContextManager & operator=(IoContextManager &&) noexcept
static IoContextManager & instance()
static Logger & instance()
Get singleton instance.
#define UNILINK_LOG_WARNING(component, operation, message)
#define UNILINK_LOG_ERROR(component, operation, message)
std::unique_ptr< WorkGuard > work_guard_
std::shared_ptr< IoContext > ioc_
std::condition_variable cv_
std::atomic< bool > running_
Impl(IoContext &external_context)
Impl(std::shared_ptr< IoContext > external_context)