diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:32:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:32:39 +0000 |
commit | 56ae875861ab260b80a030f50c4aff9f9dc8fff0 (patch) | |
tree | 531412110fc901a5918c7f7442202804a83cada9 /lib/base/fifo.cpp | |
parent | Initial commit. (diff) | |
download | icinga2-56ae875861ab260b80a030f50c4aff9f9dc8fff0.tar.xz icinga2-56ae875861ab260b80a030f50c4aff9f9dc8fff0.zip |
Adding upstream version 2.14.2.upstream/2.14.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | lib/base/fifo.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/base/fifo.cpp b/lib/base/fifo.cpp new file mode 100644 index 0000000..8653f51 --- /dev/null +++ b/lib/base/fifo.cpp @@ -0,0 +1,124 @@ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#include "base/fifo.hpp" + +using namespace icinga; + +/** + * Destructor for the FIFO class. + */ +FIFO::~FIFO() +{ + free(m_Buffer); +} + +/** + * Resizes the FIFO's buffer so that it is at least newSize bytes long. + * + * @param newSize The minimum new size of the FIFO buffer. + */ +void FIFO::ResizeBuffer(size_t newSize, bool decrease) +{ + if (m_AllocSize >= newSize && !decrease) + return; + + newSize = (newSize / FIFO::BlockSize + 1) * FIFO::BlockSize; + + if (newSize == m_AllocSize) + return; + + auto *newBuffer = static_cast<char *>(realloc(m_Buffer, newSize)); + + if (!newBuffer) + BOOST_THROW_EXCEPTION(std::bad_alloc()); + + m_Buffer = newBuffer; + + m_AllocSize = newSize; +} + +/** + * Optimizes memory usage of the FIFO buffer by reallocating + * and moving the buffer. + */ +void FIFO::Optimize() +{ + if (m_Offset > m_DataSize / 10 && m_Offset - m_DataSize > 1024) { + std::memmove(m_Buffer, m_Buffer + m_Offset, m_DataSize); + m_Offset = 0; + + if (m_DataSize > 0) + ResizeBuffer(m_DataSize, true); + + return; + } +} + +size_t FIFO::Peek(void *buffer, size_t count, bool allow_partial) +{ + ASSERT(allow_partial); + + if (count > m_DataSize) + count = m_DataSize; + + if (buffer) + std::memcpy(buffer, m_Buffer + m_Offset, count); + + return count; +} + +/** + * Implements IOQueue::Read. + */ +size_t FIFO::Read(void *buffer, size_t count, bool allow_partial) +{ + ASSERT(allow_partial); + + if (count > m_DataSize) + count = m_DataSize; + + if (buffer) + std::memcpy(buffer, m_Buffer + m_Offset, count); + + m_DataSize -= count; + m_Offset += count; + + Optimize(); + + return count; +} + +/** + * Implements IOQueue::Write. + */ +void FIFO::Write(const void *buffer, size_t count) +{ + ResizeBuffer(m_Offset + m_DataSize + count, false); + std::memcpy(m_Buffer + m_Offset + m_DataSize, buffer, count); + m_DataSize += count; + + SignalDataAvailable(); +} + +void FIFO::Close() +{ } + +bool FIFO::IsEof() const +{ + return false; +} + +size_t FIFO::GetAvailableBytes() const +{ + return m_DataSize; +} + +bool FIFO::SupportsWaiting() const +{ + return true; +} + +bool FIFO::IsDataAvailable() const +{ + return m_DataSize > 0; +} |