diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2022-11-01 10:04:13 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-11-01 14:31:48 +0000 |
commit | a9888d4ea05b04cfb7f56ac4793670bb524de996 (patch) | |
tree | e697c6badf4ce1552120778ed7f737e8267f1c28 /AK | |
parent | ab8b04368476408c41d0a2cdf68e27358a4ca5f4 (diff) | |
download | serenity-a9888d4ea05b04cfb7f56ac4793670bb524de996.zip |
AK+Kernel: Handle some allocation failures in IPv4Socket and TCPSocket
This adds try_* methods to AK::SinglyLinkedList and
AK::SinglyLinkedListWithCount and updates the network stack to use
those to gracefully handle allocation failures.
Refs #6369.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/SinglyLinkedList.h | 67 | ||||
-rw-r--r-- | AK/SinglyLinkedListWithCount.h | 14 |
2 files changed, 65 insertions, 16 deletions
diff --git a/AK/SinglyLinkedList.h b/AK/SinglyLinkedList.h index 79babf10e5..11a574495f 100644 --- a/AK/SinglyLinkedList.h +++ b/AK/SinglyLinkedList.h @@ -7,6 +7,7 @@ #pragma once #include <AK/Assertions.h> +#include <AK/Error.h> #include <AK/Find.h> #include <AK/StdLibExtras.h> #include <AK/Traits.h> @@ -148,31 +149,51 @@ public: } template<typename U = T> - void append(U&& value) + ErrorOr<void> try_append(U&& value) { - 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) { m_head = node; m_tail = node; - return; + return {}; } m_tail->next = node; m_tail = node; + return {}; } template<typename U = T> - void prepend(U&& value) + ErrorOr<void> try_prepend(U&& value) { - 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) { m_head = node; m_tail = node; - return; + return {}; } node->next = m_head; m_head = node; + return {}; + } + +#ifndef KERNEL + template<typename U = T> + void append(U&& value) + { + MUST(try_append(forward<U>(value))); } + template<typename U = T> + void prepend(U&& value) + { + MUST(try_prepend(forward<U>(value))); + } +#endif + bool contains_slow(const T& value) const { return find(value) != end(); @@ -211,32 +232,50 @@ public: } template<typename U = T> - void insert_before(Iterator iterator, U&& value) + ErrorOr<void> try_insert_before(Iterator iterator, U&& value) { - auto* node = new Node(forward<U>(value)); + auto* node = new (nothrow) Node(forward<U>(value)); + if (!node) + return Error::from_errno(ENOMEM); node->next = iterator.m_node; if (m_head == iterator.m_node) m_head = node; if (iterator.m_prev) iterator.m_prev->next = node; + return {}; } template<typename U = T> - void insert_after(Iterator iterator, U&& value) + ErrorOr<void> try_insert_after(Iterator iterator, U&& value) { - if (iterator.is_end()) { - append(value); - return; - } + if (iterator.is_end()) + return try_append(value); - auto* node = new Node(forward<U>(value)); + auto* node = new (nothrow) Node(forward<U>(value)); + if (!node) + return Error::from_errno(ENOMEM); node->next = iterator.m_node->next; iterator.m_node->next = node; if (m_tail == iterator.m_node) m_tail = node; + return {}; + } + +#ifndef KERNEL + template<typename U = T> + void insert_before(Iterator iterator, U&& value) + { + MUST(try_insert_before(iterator, forward<U>(value))); + } + + template<typename U = T> + void insert_after(Iterator iterator, U&& value) + { + MUST(try_insert_after(iterator, forward<U>(value))); } +#endif void remove(Iterator& iterator) { diff --git a/AK/SinglyLinkedListWithCount.h b/AK/SinglyLinkedListWithCount.h index 4f47ef7a24..39de628610 100644 --- a/AK/SinglyLinkedListWithCount.h +++ b/AK/SinglyLinkedListWithCount.h @@ -60,11 +60,21 @@ public: } template<typename U = T> + ErrorOr<void> try_append(U&& value) + { + auto result = List::try_append(forward<T>(value)); + if (!result.is_error()) + m_count++; + return result; + } + +#ifndef KERNEL + template<typename U = T> void append(U&& value) { - m_count++; - return List::append(forward<T>(value)); + MUST(try_append(forward<T>(value))); } +#endif bool contains_slow(const T& value) const { |