Program Listing for File Buffer.cpp
↰ Return to documentation for file (BackendAsyncmsg/Buffer.cpp
)
#include "Buffer.hpp"
netio3::asyncmsg::BufferManager::BufferManager(const netio3::ConnectionParameters& params) :
m_buffers{initBuffers(params)}, m_minNumAvailableBuffers{m_buffers.size()}
{
for (const auto& [key, buffer] : m_buffers) {
m_availableBuffers.push(key);
}
}
[[nodiscard]] netio3::NetworkBuffer* netio3::asyncmsg::BufferManager::getBuffer()
{
if (m_buffers.empty()) {
throw TcpNoBuffers(ERS_HERE);
return nullptr;
}
if (m_availableBuffers.empty()) {
return nullptr;
}
auto key = decltype(m_availableBuffers)::value_type{};
const auto success = m_availableBuffers.try_pop(key);
if (not success) {
return nullptr;
}
m_minNumAvailableBuffers.store(
std::min(static_cast<std::size_t>(std::max(m_availableBuffers.size(), 0L)),
m_minNumAvailableBuffers.load(std::memory_order_relaxed)),
std::memory_order_relaxed);
auto& buffer = m_buffers.at(key);
return &buffer;
}
std::map<netio3::asyncmsg::Key, netio3::asyncmsg::Buffer>
netio3::asyncmsg::BufferManager::initBuffers(const ConnectionParameters& params)
{
if (params.mr_start != nullptr) {
return {};
}
std::map<Key, Buffer> buffers;
std::generate_n(
std::inserter(buffers, buffers.end()), params.num_buf, [¶ms, key = 0]() mutable {
auto buffer = std::make_pair(key, Buffer(params.buf_size, key));
++key;
return buffer;
});
return buffers;
}
void netio3::asyncmsg::BufferManager::returnBuffer(const netio3::NetworkBuffer* buffer)
{
const auto* buf = dynamic_cast<const Buffer*>(buffer);
if (buf == nullptr) {
throw std::invalid_argument("BufferManager::returnBuffer: buffer is not of type Buffer");
}
m_availableBuffers.push(buf->getKey());
}
void netio3::asyncmsg::BufferManager::returnBuffer(Key key)
{
m_availableBuffers.push(key);
}
std::size_t netio3::asyncmsg::BufferManager::getNumAvailableBuffers()
{
return m_minNumAvailableBuffers.exchange(
static_cast<std::size_t>(std::max(m_availableBuffers.size(), 0L)), std::memory_order_relaxed);
}