From b04fbd7eb17153c81d9e7fa3bbe6f666e2542896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Thu, 17 Aug 2023 19:56:11 -0400 Subject: [PATCH] upnp: use dedicated io_context if none provided Change-Id: I8482f636007e3625576f5fc9f6f95c3d5be6d2bb --- include/upnp/upnp_context.h | 5 +++++ src/upnp/upnp_context.cpp | 28 +++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/upnp/upnp_context.h b/include/upnp/upnp_context.h index cabfbba..3f24bca 100644 --- a/include/upnp/upnp_context.h +++ b/include/upnp/upnp_context.h @@ -107,6 +107,8 @@ public: UPnPContext(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger); ~UPnPContext(); + std::shared_ptr<asio::io_context> createIoContext(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger); + // Terminate the instance. void shutdown(); @@ -311,6 +313,9 @@ private: // Shutdown synchronization bool shutdownComplete_ {false}; + + // Thread + std::unique_ptr<std::thread> ioContextRunner_; }; } // namespace upnp diff --git a/src/upnp/upnp_context.cpp b/src/upnp/upnp_context.cpp index 335f70b..9d79f49 100644 --- a/src/upnp/upnp_context.cpp +++ b/src/upnp/upnp_context.cpp @@ -44,7 +44,7 @@ constexpr static uint16_t UPNP_UDP_PORT_MIN {20000}; constexpr static uint16_t UPNP_UDP_PORT_MAX {UPNP_UDP_PORT_MIN + 5000}; UPnPContext::UPnPContext(const std::shared_ptr<asio::io_context>& ioContext, const std::shared_ptr<dht::log::Logger>& logger) - : mappingListUpdateTimer_(*ioContext), ctx(ioContext), logger_(logger) + : ctx(createIoContext(ioContext, logger)), mappingListUpdateTimer_(*ioContext), logger_(logger) { if (logger_) logger_->debug("Creating UPnPContext instance [{}]", fmt::ptr(this)); @@ -55,6 +55,25 @@ UPnPContext::UPnPContext(const std::shared_ptr<asio::io_context>& ioContext, con ctx->post([this] { init(); }); } +std::shared_ptr<asio::io_context> +UPnPContext::createIoContext(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger) { + if (ctx) { + return ctx; + } else { + if (logger) logger->debug("UPnPContext: starting dedicated io_context thread"); + auto ioCtx = std::make_shared<asio::io_context>(); + ioContextRunner_ = std::make_unique<std::thread>([ioCtx, l=logger]() { + try { + auto work = asio::make_work_guard(*ioCtx); + ioCtx->run(); + } catch (const std::exception& ex) { + if (l) l->error("Unexpected io_context thread exception: {}", ex.what()); + } + }); + return ioCtx; + } +} + void UPnPContext::shutdown(std::condition_variable& cv) { @@ -75,6 +94,13 @@ UPnPContext::shutdown(std::condition_variable& cv) shutdownComplete_ = true; cv.notify_one(); } + + if (ioContextRunner_) { + if (logger_) logger_->debug("UPnPContext: stopping io_context thread"); + ctx->stop(); + ioContextRunner_->join(); + ioContextRunner_.reset(); + } } void -- GitLab