#ifndef LIBREPOMGR_MULTI_SESSION_H #define LIBREPOMGR_MULTI_SESSION_H #include #include #include #include #include #include namespace LibRepoMgr { template class MultiSession { public: using ContainerType = std::vector; using HandlerType = std::function; using SharedPointerType = std::shared_ptr>; explicit MultiSession(boost::asio::io_context &ioContext, HandlerType &&handler); ~MultiSession(); static SharedPointerType create(boost::asio::io_context &ioContext, HandlerType &&handler); void addResponses(const ContainerType &); void addResponse(SessionResponse &&); protected: boost::asio::io_context &ioContext(); ContainerType &allResponses(); const ContainerType &allResponses() const; private: boost::asio::io_context &m_ioContext; HandlerType m_handler; ContainerType m_allResponses; std::mutex m_mutex; }; template inline MultiSession::MultiSession(boost::asio::io_context &ioContext, HandlerType &&handler) : m_ioContext(ioContext) , m_handler(handler) { } template inline MultiSession::~MultiSession() { boost::asio::post(m_ioContext.get_executor(), [handler = std::move(m_handler), allResponses = std::move(m_allResponses)]() mutable { handler(std::move(allResponses)); }); } template inline void MultiSession::addResponses(const ContainerType &responses) { const auto lock = std::unique_lock(m_mutex); m_allResponses.insert(m_allResponses.end(), responses.begin(), responses.end()); } template inline void MultiSession::addResponse(SessionResponse &&response) { const auto lock = std::unique_lock(m_mutex); m_allResponses.emplace_back(std::move(response)); } template inline boost::asio::io_context &MultiSession::ioContext() { return m_ioContext; } template inline typename MultiSession::ContainerType &MultiSession::allResponses() { return m_allResponses; } template inline const typename MultiSession::ContainerType &MultiSession::allResponses() const { return m_allResponses; } template inline typename MultiSession::SharedPointerType MultiSession::create( boost::asio::io_context &ioContext, MultiSession::HandlerType &&handler) { return std::make_shared>(ioContext, std::move(handler)); } template <> class MultiSession { public: using HandlerType = std::function; using SharedPointerType = std::shared_ptr>; explicit MultiSession(boost::asio::io_context &ioContext, HandlerType &&handler); ~MultiSession(); static std::shared_ptr> create(boost::asio::io_context &ioContext, HandlerType &&handler); protected: boost::asio::io_context &ioContext(); private: boost::asio::io_context &m_ioContext; HandlerType m_handler; }; inline MultiSession::MultiSession(boost::asio::io_context &ioContext, HandlerType &&handler) : m_ioContext(ioContext) , m_handler(handler) { } inline MultiSession::~MultiSession() { boost::asio::post(m_ioContext.get_executor(), std::move(m_handler)); } inline typename MultiSession::SharedPointerType MultiSession::create( boost::asio::io_context &ioContext, MultiSession::HandlerType &&handler) { return std::make_shared>(ioContext, std::move(handler)); } inline boost::asio::io_context &MultiSession::ioContext() { return m_ioContext; } } // namespace LibRepoMgr #endif // LIBREPOMGR_MULTI_SESSION_H