소스 검색

Kernel: Make KBuffer a value-type wrapper around a KBufferImpl

A KBuffer always contains a valid KBufferImpl. If you need a "null"
state buffer, use Optional<KBuffer>.

This makes KBuffer very easy to work with and pass around, just like
ByteBuffer before it.
Andreas Kling 6 년 전
부모
커밋
605975adb5
6개의 변경된 파일50개의 추가작업 그리고 22개의 파일을 삭제
  1. 33 5
      Kernel/KBuffer.h
  2. 6 6
      Kernel/Net/IPv4Socket.cpp
  3. 2 2
      Kernel/Net/IPv4Socket.h
  4. 1 1
      Kernel/Net/NetworkAdapter.cpp
  5. 2 2
      Kernel/Net/NetworkAdapter.h
  6. 6 6
      Kernel/Net/NetworkTask.cpp

+ 33 - 5
Kernel/KBuffer.h

@@ -4,16 +4,16 @@
 #include <Kernel/VM/MemoryManager.h>
 #include <Kernel/VM/Region.h>
 
-class KBuffer : public RefCounted<KBuffer> {
+class KBufferImpl : public RefCounted<KBufferImpl> {
 public:
-    static NonnullRefPtr<KBuffer> create_with_size(size_t size)
+    static NonnullRefPtr<KBufferImpl> create_with_size(size_t size)
     {
         auto region = MM.allocate_kernel_region(PAGE_ROUND_UP(size), "KBuffer");
         ASSERT(region);
-        return adopt(*new KBuffer(*region, size));
+        return adopt(*new KBufferImpl(*region, size));
     }
 
-    static NonnullRefPtr<KBuffer> copy(const void* data, size_t size)
+    static NonnullRefPtr<KBufferImpl> copy(const void* data, size_t size)
     {
         auto buffer = create_with_size(size);
         memcpy(buffer->data(), data, size);
@@ -26,7 +26,7 @@ public:
     size_t capacity() const { return m_region->size(); }
 
 private:
-    explicit KBuffer(NonnullRefPtr<Region>&& region, size_t size)
+    explicit KBufferImpl(NonnullRefPtr<Region>&& region, size_t size)
         : m_size(size)
         , m_region(move(region))
     {
@@ -35,3 +35,31 @@ private:
     size_t m_size { 0 };
     NonnullRefPtr<Region> m_region;
 };
+
+class KBuffer {
+public:
+    static KBuffer create_with_size(size_t size)
+    {
+        return KBuffer(KBufferImpl::create_with_size(size));
+    }
+
+    static KBuffer copy(const void* data, size_t size)
+    {
+        return KBuffer(KBufferImpl::copy(data, size));
+    }
+
+    u8* data() { return m_impl->data(); }
+    const u8* data() const { return m_impl->data(); }
+    size_t size() const { return m_impl->size(); }
+    size_t capacity() const { return m_impl->size(); }
+
+    const KBufferImpl& impl() const { return m_impl; }
+
+    KBuffer(NonnullRefPtr<KBufferImpl>&& impl)
+        : m_impl(move(impl))
+    {
+    }
+
+private:
+    NonnullRefPtr<KBufferImpl> m_impl;
+};

+ 6 - 6
Kernel/Net/IPv4Socket.cpp

@@ -192,7 +192,7 @@ ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t
 #endif
         }
     }
-    if (packet.data.is_null()) {
+    if (!packet.data.has_value()) {
         if (protocol_is_disconnected()) {
             kprintf("IPv4Socket{%p} is protocol-disconnected, returning 0 in recvfrom!\n", this);
             return 0;
@@ -217,8 +217,8 @@ ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t
         kprintf("IPv4Socket(%p): recvfrom with blocking %d bytes, packets in queue: %d\n", this, packet.data.size(), m_receive_queue.size_slow());
 #endif
     }
-    ASSERT(!packet.data.is_null());
-    auto& ipv4_packet = *(const IPv4Packet*)(packet.data->data());
+    ASSERT(packet.data.has_value());
+    auto& ipv4_packet = *(const IPv4Packet*)(packet.data.value().data());
 
     if (addr) {
         dbgprintf("Incoming packet is from: %s:%u\n", packet.peer_address.to_string().characters(), packet.peer_port);
@@ -236,13 +236,13 @@ ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t
         return ipv4_packet.payload_size();
     }
 
-    return protocol_receive(*packet.data, buffer, buffer_length, flags);
+    return protocol_receive(packet.data.value(), buffer, buffer_length, flags);
 }
 
-void IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, NonnullRefPtr<KBuffer>&& packet)
+void IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, KBuffer&& packet)
 {
     LOCKER(lock());
-    auto packet_size = packet->size();
+    auto packet_size = packet.size();
     m_receive_queue.append({ source_address, source_port, move(packet) });
     m_can_read = true;
     m_bytes_received += packet_size;

+ 2 - 2
Kernel/Net/IPv4Socket.h

@@ -32,7 +32,7 @@ public:
     virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
     virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
 
-    void did_receive(const IPv4Address& peer_address, u16 peer_port, NonnullRefPtr<KBuffer>&&);
+    void did_receive(const IPv4Address& peer_address, u16 peer_port, KBuffer&&);
 
     const IPv4Address& local_address() const;
     u16 local_port() const { return m_local_port; }
@@ -64,7 +64,7 @@ private:
     struct ReceivedPacket {
         IPv4Address peer_address;
         u16 peer_port;
-        RefPtr<KBuffer> data;
+        Optional<KBuffer> data;
     };
 
     SinglyLinkedList<ReceivedPacket> m_receive_queue;

+ 1 - 1
Kernel/Net/NetworkAdapter.cpp

@@ -84,7 +84,7 @@ void NetworkAdapter::did_receive(const u8* data, int length)
     m_packet_queue.append(KBuffer::copy(data, length));
 }
 
-RefPtr<KBuffer> NetworkAdapter::dequeue_packet()
+Optional<KBuffer> NetworkAdapter::dequeue_packet()
 {
     InterruptDisabler disabler;
     if (m_packet_queue.is_empty())

+ 2 - 2
Kernel/Net/NetworkAdapter.h

@@ -29,7 +29,7 @@ public:
     void send(const MACAddress&, const ARPPacket&);
     void send_ipv4(const MACAddress&, const IPv4Address&, IPv4Protocol, const u8* payload, size_t payload_size);
 
-    RefPtr<KBuffer> dequeue_packet();
+    Optional<KBuffer> dequeue_packet();
 
     bool has_queued_packets() const { return !m_packet_queue.is_empty(); }
 
@@ -43,6 +43,6 @@ protected:
 private:
     MACAddress m_mac_address;
     IPv4Address m_ipv4_address;
-    SinglyLinkedList<NonnullRefPtr<KBuffer>> m_packet_queue;
+    SinglyLinkedList<KBuffer> m_packet_queue;
     String m_name;
 };

+ 6 - 6
Kernel/Net/NetworkTask.cpp

@@ -44,11 +44,11 @@ void NetworkTask_main()
     if (adapter)
         adapter->set_ipv4_address(IPv4Address(192, 168, 5, 2));
 
-    auto dequeue_packet = [&]() -> RefPtr<KBuffer> {
+    auto dequeue_packet = [&]() -> Optional<KBuffer> {
         auto packet = LoopbackAdapter::the().dequeue_packet();
-        if (!packet.is_null()) {
-            dbgprintf("Receive loopback packet (%d bytes)\n", packet->size());
-            return packet;
+        if (packet.has_value()) {
+            dbgprintf("Receive loopback packet (%d bytes)\n", packet.value().size());
+            return packet.value();
         }
         if (adapter && adapter->has_queued_packets())
             return adapter->dequeue_packet();
@@ -58,7 +58,7 @@ void NetworkTask_main()
     kprintf("NetworkTask: Enter main loop.\n");
     for (;;) {
         auto packet_maybe_null = dequeue_packet();
-        if (packet_maybe_null.is_null()) {
+        if (!packet_maybe_null.has_value()) {
             (void)current->block_until("Networking", [] {
                 if (LoopbackAdapter::the().has_queued_packets())
                     return true;
@@ -70,7 +70,7 @@ void NetworkTask_main()
             });
             continue;
         }
-        auto& packet = *packet_maybe_null;
+        auto& packet = packet_maybe_null.value();
         if (packet.size() < (int)(sizeof(EthernetFrameHeader))) {
             kprintf("NetworkTask: Packet is too small to be an Ethernet packet! (%d)\n", packet.size());
             continue;