diff options
author | Justin <sw1tchbl4d3@sw1tchbl4d3.com> | 2021-04-28 23:22:21 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-29 08:09:53 +0200 |
commit | 2d098c88dc64cbf58e3eb09a39fb917e78360685 (patch) | |
tree | 6c30c6f271ec26e162e60bf4f82abf9826ccca07 /Kernel | |
parent | 9bcdbe205b02078f7a6ff01d8769efe4617e60be (diff) | |
download | serenity-2d098c88dc64cbf58e3eb09a39fb917e78360685.zip |
Kernel: Implement peek() function for DoubleBuffer
This allows us to "peek" into a DoubleBuffer without incrementing
the m_read_buffer_index, which is needed to implement MSG_PEEK.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/DoubleBuffer.cpp | 21 | ||||
-rw-r--r-- | Kernel/DoubleBuffer.h | 6 |
2 files changed, 25 insertions, 2 deletions
diff --git a/Kernel/DoubleBuffer.cpp b/Kernel/DoubleBuffer.cpp index ef5fd497e1..2d3b39adac 100644 --- a/Kernel/DoubleBuffer.cpp +++ b/Kernel/DoubleBuffer.cpp @@ -44,7 +44,6 @@ ssize_t DoubleBuffer::write(const UserOrKernelBuffer& data, size_t size) { if (!size || m_storage.is_null()) return 0; - VERIFY(size > 0); Locker locker(m_lock); size_t bytes_to_write = min(size, m_space_for_writing); u8* write_ptr = m_write_buffer->data + m_write_buffer->size; @@ -61,7 +60,6 @@ ssize_t DoubleBuffer::read(UserOrKernelBuffer& data, size_t size) { if (!size || m_storage.is_null()) return 0; - VERIFY(size > 0); Locker locker(m_lock); if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0) flip(); @@ -77,4 +75,23 @@ ssize_t DoubleBuffer::read(UserOrKernelBuffer& data, size_t size) return (ssize_t)nread; } +ssize_t DoubleBuffer::peek(UserOrKernelBuffer& data, size_t size) +{ + if (!size || m_storage.is_null()) + return 0; + Locker locker(m_lock); + if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0) { + flip(); + } + if (m_read_buffer_index >= m_read_buffer->size) + return 0; + size_t nread = min(m_read_buffer->size - m_read_buffer_index, size); + if (!data.write(m_read_buffer->data + m_read_buffer_index, nread)) + return -EFAULT; + compute_lockfree_metadata(); + if (m_unblock_callback && m_space_for_writing > 0) + m_unblock_callback(); + return (ssize_t)nread; +} + } diff --git a/Kernel/DoubleBuffer.h b/Kernel/DoubleBuffer.h index fc3b3472db..8bf58f7532 100644 --- a/Kernel/DoubleBuffer.h +++ b/Kernel/DoubleBuffer.h @@ -29,6 +29,12 @@ public: auto buffer = UserOrKernelBuffer::for_kernel_buffer(data); return read(buffer, size); } + [[nodiscard]] ssize_t peek(UserOrKernelBuffer&, size_t); + [[nodiscard]] ssize_t peek(u8* data, size_t size) + { + auto buffer = UserOrKernelBuffer::for_kernel_buffer(data); + return peek(buffer, size); + } bool is_empty() const { return m_empty; } |