mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
AK+Kernel: Handle allocation failures in Device::try_make_request
This adds try_* methods to AK::DoublyLinkedList and updates the Device class to use those to gracefully handle allocation failures. Refs #6369.
This commit is contained in:
parent
b33834ca3a
commit
ab8b043684
Notes:
sideshowbarker
2024-07-17 20:33:50 +09:00
Author: https://github.com/gunnarbeutner Commit: https://github.com/SerenityOS/serenity/commit/ab8b043684 Pull-request: https://github.com/SerenityOS/serenity/pull/15875 Reviewed-by: https://github.com/linusg
2 changed files with 28 additions and 7 deletions
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
|
#include <AK/Error.h>
|
||||||
#include <AK/Find.h>
|
#include <AK/Find.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
|
|
||||||
|
@ -91,42 +92,62 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
void append(U&& value)
|
ErrorOr<void> try_append(U&& value)
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
requires { T(value); }, "Conversion operator is missing.");
|
requires { T(value); }, "Conversion operator is missing.");
|
||||||
auto* node = new Node(forward<U>(value));
|
auto* node = new (nothrow) Node(forward<U>(value));
|
||||||
|
if (!node)
|
||||||
|
return Error::from_errno(ENOMEM);
|
||||||
if (!m_head) {
|
if (!m_head) {
|
||||||
VERIFY(!m_tail);
|
VERIFY(!m_tail);
|
||||||
m_head = node;
|
m_head = node;
|
||||||
m_tail = node;
|
m_tail = node;
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
VERIFY(m_tail);
|
VERIFY(m_tail);
|
||||||
VERIFY(!node->next);
|
VERIFY(!node->next);
|
||||||
m_tail->next = node;
|
m_tail->next = node;
|
||||||
node->prev = m_tail;
|
node->prev = m_tail;
|
||||||
m_tail = node;
|
m_tail = node;
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
void prepend(U&& value)
|
ErrorOr<void> try_prepend(U&& value)
|
||||||
{
|
{
|
||||||
static_assert(IsSame<T, U>);
|
static_assert(IsSame<T, U>);
|
||||||
auto* node = new Node(forward<U>(value));
|
auto* node = new (nothrow) Node(forward<U>(value));
|
||||||
|
if (!node)
|
||||||
|
return Error::from_errno(ENOMEM);
|
||||||
if (!m_head) {
|
if (!m_head) {
|
||||||
VERIFY(!m_tail);
|
VERIFY(!m_tail);
|
||||||
m_head = node;
|
m_head = node;
|
||||||
m_tail = node;
|
m_tail = node;
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
VERIFY(m_tail);
|
VERIFY(m_tail);
|
||||||
VERIFY(!node->prev);
|
VERIFY(!node->prev);
|
||||||
m_head->prev = node;
|
m_head->prev = node;
|
||||||
node->next = m_head;
|
node->next = m_head;
|
||||||
m_head = node;
|
m_head = node;
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef KERNEL
|
||||||
|
template<typename U>
|
||||||
|
void append(U&& value)
|
||||||
|
{
|
||||||
|
MUST(try_append(forward<U>(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
void prepend(U&& value)
|
||||||
|
{
|
||||||
|
MUST(try_prepend(forward<U>(value)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] bool contains_slow(const T& value) const
|
[[nodiscard]] bool contains_slow(const T& value) const
|
||||||
{
|
{
|
||||||
return find(value) != end();
|
return find(value) != end();
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
auto request = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) AsyncRequestType(*this, forward<Args>(args)...)));
|
auto request = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) AsyncRequestType(*this, forward<Args>(args)...)));
|
||||||
SpinlockLocker lock(m_requests_lock);
|
SpinlockLocker lock(m_requests_lock);
|
||||||
bool was_empty = m_requests.is_empty();
|
bool was_empty = m_requests.is_empty();
|
||||||
m_requests.append(request);
|
TRY(m_requests.try_append(request));
|
||||||
if (was_empty)
|
if (was_empty)
|
||||||
request->do_start(move(lock));
|
request->do_start(move(lock));
|
||||||
return request;
|
return request;
|
||||||
|
|
Loading…
Reference in a new issue