1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:27:43 +00:00

Kernel: Add DoubleBuffer::try_create() factory method for OOM hardening

We need to expose the ability for DoubleBuffer creation to expose
failure, as DoubleBuffer depends on KBuffer, which also has to be able
to expose failure during OOM.

We will remove the non OOM API once all users have been converted.
This commit is contained in:
Brian Gianforcaro 2021-08-01 01:40:07 -07:00 committed by Andreas Kling
parent b6200a3ed8
commit f816abcbad
2 changed files with 24 additions and 9 deletions

View file

@ -17,22 +17,36 @@ inline void DoubleBuffer::compute_lockfree_metadata()
m_space_for_writing = m_capacity - m_write_buffer->size;
}
OwnPtr<DoubleBuffer> DoubleBuffer::try_create(size_t capacity)
{
auto storage = KBuffer::try_create_with_size(capacity * 2, Region::Access::Read | Region::Access::Write, "DoubleBuffer");
if (!storage)
return {};
return adopt_own_if_nonnull(new (nothrow) DoubleBuffer(capacity, storage.release_nonnull()));
}
DoubleBuffer::DoubleBuffer(size_t capacity)
: DoubleBuffer(capacity, KBuffer::try_create_with_size(capacity * 2, Region::Access::Read | Region::Access::Write, "DoubleBuffer").release_nonnull())
{
}
DoubleBuffer::DoubleBuffer(size_t capacity, NonnullOwnPtr<KBuffer> storage)
: m_write_buffer(&m_buffer1)
, m_read_buffer(&m_buffer2)
, m_storage(KBuffer::create_with_size(capacity * 2, Region::Access::Read | Region::Access::Write, "DoubleBuffer"))
, m_storage(move(storage))
, m_capacity(capacity)
{
m_buffer1.data = m_storage.data();
m_buffer1.data = m_storage->data();
m_buffer1.size = 0;
m_buffer2.data = m_storage.data() + capacity;
m_buffer2.data = m_storage->data() + capacity;
m_buffer2.size = 0;
m_space_for_writing = capacity;
}
void DoubleBuffer::flip()
{
if (m_storage.is_null())
if (m_storage->is_null())
return;
VERIFY(m_read_buffer_index == m_read_buffer->size);
swap(m_read_buffer, m_write_buffer);
@ -43,7 +57,7 @@ void DoubleBuffer::flip()
KResultOr<size_t> DoubleBuffer::write(const UserOrKernelBuffer& data, size_t size)
{
if (!size || m_storage.is_null())
if (!size || m_storage->is_null())
return 0;
MutexLocker locker(m_lock);
size_t bytes_to_write = min(size, m_space_for_writing);
@ -59,7 +73,7 @@ KResultOr<size_t> DoubleBuffer::write(const UserOrKernelBuffer& data, size_t siz
KResultOr<size_t> DoubleBuffer::read(UserOrKernelBuffer& data, size_t size)
{
if (!size || m_storage.is_null())
if (!size || m_storage->is_null())
return 0;
MutexLocker locker(m_lock);
if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0)
@ -78,7 +92,7 @@ KResultOr<size_t> DoubleBuffer::read(UserOrKernelBuffer& data, size_t size)
KResultOr<size_t> DoubleBuffer::peek(UserOrKernelBuffer& data, size_t size)
{
if (!size || m_storage.is_null())
if (!size || m_storage->is_null())
return 0;
MutexLocker locker(m_lock);
if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0) {