summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Net/NetworkAdapter.cpp40
-rw-r--r--Kernel/Net/NetworkAdapter.h20
2 files changed, 37 insertions, 23 deletions
diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp
index e1b3a999a4..e453c325d9 100644
--- a/Kernel/Net/NetworkAdapter.cpp
+++ b/Kernel/Net/NetworkAdapter.cpp
@@ -153,27 +153,34 @@ void NetworkAdapter::did_receive(ReadonlyBytes payload)
m_packets_in++;
m_bytes_in += payload.size();
- Optional<KBuffer> buffer;
-
if (m_packet_queue_size == max_packet_buffers) {
// FIXME: Keep track of the number of dropped packets
return;
}
- if (m_unused_packet_buffers.is_empty()) {
- buffer = KBuffer::copy(payload.data(), payload.size());
+ RefPtr<PacketWithTimestamp> packet;
+
+ if (m_unused_packets.is_empty()) {
+ auto buffer = KBuffer::copy(payload.data(), payload.size());
+ packet = adopt_ref_if_nonnull(new PacketWithTimestamp { move(buffer), kgettimeofday() });
} else {
- buffer = m_unused_packet_buffers.take_first();
- --m_unused_packet_buffers_count;
- if (payload.size() <= buffer.value().capacity()) {
- memcpy(buffer.value().data(), payload.data(), payload.size());
- buffer.value().set_size(payload.size());
+ packet = m_unused_packets.take_first();
+ if (payload.size() <= packet->buffer.capacity()) {
+ memcpy(packet->buffer.data(), payload.data(), payload.size());
+ packet->buffer.set_size(payload.size());
+ packet->timestamp = kgettimeofday();
} else {
- buffer = KBuffer::copy(payload.data(), payload.size());
+ auto buffer = KBuffer::copy(payload.data(), payload.size());
+ packet = adopt_ref_if_nonnull(new PacketWithTimestamp { move(buffer), kgettimeofday() });
}
}
- m_packet_queue.append({ buffer.value(), kgettimeofday() });
+ if (!packet) {
+ dbgln("Discarding packet because we're out of memory");
+ return;
+ }
+
+ m_packet_queue.append(*packet);
m_packet_queue_size++;
if (on_receive)
@@ -187,13 +194,12 @@ size_t NetworkAdapter::dequeue_packet(u8* buffer, size_t buffer_size, Time& pack
return 0;
auto packet_with_timestamp = m_packet_queue.take_first();
m_packet_queue_size--;
- packet_timestamp = packet_with_timestamp.timestamp;
- auto packet = move(packet_with_timestamp.packet);
- size_t packet_size = packet.size();
+ packet_timestamp = packet_with_timestamp->timestamp;
+ auto& packet_buffer = packet_with_timestamp->buffer;
+ size_t packet_size = packet_buffer.size();
VERIFY(packet_size <= buffer_size);
- memcpy(buffer, packet.data(), packet_size);
- m_unused_packet_buffers.append(packet);
- ++m_unused_packet_buffers_count;
+ memcpy(buffer, packet_buffer.data(), packet_size);
+ m_unused_packets.append(*packet_with_timestamp);
return packet_size;
}
diff --git a/Kernel/Net/NetworkAdapter.h b/Kernel/Net/NetworkAdapter.h
index f1477f6e22..14748520c1 100644
--- a/Kernel/Net/NetworkAdapter.h
+++ b/Kernel/Net/NetworkAdapter.h
@@ -8,8 +8,8 @@
#include <AK/ByteBuffer.h>
#include <AK/Function.h>
+#include <AK/IntrusiveList.h>
#include <AK/MACAddress.h>
-#include <AK/SinglyLinkedList.h>
#include <AK/Types.h>
#include <AK/WeakPtr.h>
#include <AK/Weakable.h>
@@ -86,18 +86,26 @@ private:
IPv4Address m_ipv4_netmask;
IPv4Address m_ipv4_gateway;
- struct PacketWithTimestamp {
- KBuffer packet;
+ struct PacketWithTimestamp : public RefCounted<PacketWithTimestamp> {
+ PacketWithTimestamp(KBuffer buffer, Time timestamp)
+ : buffer(move(buffer))
+ , timestamp(timestamp)
+ {
+ }
+
+ KBuffer buffer;
Time timestamp;
+ IntrusiveListNode<PacketWithTimestamp, RefPtr<PacketWithTimestamp>> packet_node;
};
// FIXME: Make this configurable
static constexpr size_t max_packet_buffers = 1024;
- SinglyLinkedList<PacketWithTimestamp> m_packet_queue;
+ using PacketList = IntrusiveList<PacketWithTimestamp, RefPtr<PacketWithTimestamp>, &PacketWithTimestamp::packet_node>;
+
+ PacketList m_packet_queue;
size_t m_packet_queue_size { 0 };
- SinglyLinkedList<KBuffer> m_unused_packet_buffers;
- size_t m_unused_packet_buffers_count { 0 };
+ PacketList m_unused_packets;
String m_name;
u32 m_packets_in { 0 };
u32 m_bytes_in { 0 };