arch-repo-manager/librepomgr/multisession.h

130 lines
4.0 KiB
C++

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