From d9f3a7761ae1bb8d79aac64a850c110402f1ec53 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Tue, 18 Mar 2025 20:55:17 +0800 Subject: [PATCH] Notify socket events directly --- kernel/libs/aster-bigtcp/src/iface/common.rs | 17 --------- .../aster-bigtcp/src/socket/bound/common.rs | 36 ++++--------------- .../aster-bigtcp/src/socket/bound/tcp_conn.rs | 6 ++-- .../libs/aster-bigtcp/src/socket/bound/udp.rs | 4 +-- kernel/libs/aster-bigtcp/src/socket_table.rs | 14 +------- 5 files changed, 12 insertions(+), 65 deletions(-) diff --git a/kernel/libs/aster-bigtcp/src/iface/common.rs b/kernel/libs/aster-bigtcp/src/iface/common.rs index b6f1e668..b29883e9 100644 --- a/kernel/libs/aster-bigtcp/src/iface/common.rs +++ b/kernel/libs/aster-bigtcp/src/iface/common.rs @@ -202,23 +202,6 @@ impl IfaceCommon { } } - // Notify all socket events. - for socket in sockets.tcp_listener_iter() { - if socket.has_events() { - socket.on_events(); - } - } - for socket in sockets.tcp_conn_iter() { - if socket.has_events() { - socket.on_events(); - } - } - for socket in sockets.udp_socket_iter() { - if socket.has_events() { - socket.on_events(); - } - } - // Note that only TCP connections can have timers set, so as far as the time to poll is // concerned, we only need to consider TCP connections. interface.next_poll_at_ms() diff --git a/kernel/libs/aster-bigtcp/src/socket/bound/common.rs b/kernel/libs/aster-bigtcp/src/socket/bound/common.rs index 3965ed53..2f2e8671 100644 --- a/kernel/libs/aster-bigtcp/src/socket/bound/common.rs +++ b/kernel/libs/aster-bigtcp/src/socket/bound/common.rs @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 use alloc::sync::{Arc, Weak}; -use core::sync::atomic::{AtomicU8, Ordering}; use smoltcp::wire::IpEndpoint; use spin::once::Once; @@ -45,7 +44,6 @@ pub struct SocketBg, E: Ext> { pub(super) bound: BoundPort, pub(super) inner: T, observer: Once, - events: AtomicU8, } impl, E: Ext> Drop for Socket { @@ -62,7 +60,6 @@ impl, E: Ext> Socket { bound, inner, observer: Once::new(), - events: AtomicU8::new(0), }))) } @@ -74,7 +71,6 @@ impl, E: Ext> Socket { bound, inner: inner_fn(weak), observer: Once::new(), - events: AtomicU8::new(0), }))) } @@ -110,44 +106,24 @@ define_boolean_value!( ); impl, E: Ext> SocketBg { - pub(crate) fn has_events(&self) -> bool { - self.events.load(Ordering::Relaxed) != 0 - } - - pub(crate) fn on_events(&self) { - // This method can only be called to process network events, so we assume we are holding the - // poll lock and no race conditions can occur. - let events = self.events.load(Ordering::Relaxed); - self.events.store(0, Ordering::Relaxed); - - if let Some(observer) = self.observer.get() { - observer.on_events(SocketEvents::from_bits_truncate(events)); - } - } - - pub(crate) fn on_dead_events(self: Arc) + pub(crate) fn notify_dead_events(self: Arc) where T::Observer: Clone, { - // There is no need to clear the events because the socket is dead. - let events = self.events.load(Ordering::Relaxed); - let observer = self.observer.get().cloned(); drop(self); // Notify dead events after the `Arc` is dropped to ensure the observer sees this event // with the expected reference count. See `TcpConnection::connect_state` for an example. if let Some(ref observer) = observer { - observer.on_events(SocketEvents::from_bits_truncate(events)); + observer.on_events(SocketEvents::CLOSED_SEND | SocketEvents::CLOSED_RECV); } } - pub(super) fn add_events(&self, new_events: SocketEvents) { - // This method can only be called to add network events, so we assume we are holding the - // poll lock and no race conditions can occur. - let events = self.events.load(Ordering::Relaxed); - self.events - .store(events | new_events.bits(), Ordering::Relaxed); + pub(super) fn notify_events(&self, new_events: SocketEvents) { + if let Some(observer) = self.observer.get() { + observer.on_events(new_events); + } } } diff --git a/kernel/libs/aster-bigtcp/src/socket/bound/tcp_conn.rs b/kernel/libs/aster-bigtcp/src/socket/bound/tcp_conn.rs index 3227b0bb..ec60ff28 100644 --- a/kernel/libs/aster-bigtcp/src/socket/bound/tcp_conn.rs +++ b/kernel/libs/aster-bigtcp/src/socket/bound/tcp_conn.rs @@ -165,7 +165,7 @@ impl RawTcpSocketExt { if let Some(value) = backlog.connecting.remove(this.connection_key()) { backlog.connected.push(value); } - listener.add_events(SocketEvents::CAN_RECV); + listener.notify_events(SocketEvents::CAN_RECV); } } @@ -621,7 +621,7 @@ impl TcpConnectionBg { socket.check_state(self, old_state, old_recv_queue, is_rst); events |= state_events; - self.add_events(events); + self.notify_events(events); let poll_at = socket.poll_at(iface.context_mut()); iface.update_next_poll_at_ms(self, poll_at); @@ -669,7 +669,7 @@ impl TcpConnectionBg { socket.check_state(self, old_state, old_recv_queue, is_rst); events |= state_events; - self.add_events(events); + self.notify_events(events); let poll_at = socket.poll_at(iface.context_mut()); iface.update_next_poll_at_ms(self, poll_at); diff --git a/kernel/libs/aster-bigtcp/src/socket/bound/udp.rs b/kernel/libs/aster-bigtcp/src/socket/bound/udp.rs index 61b67d8c..e3c5ccba 100644 --- a/kernel/libs/aster-bigtcp/src/socket/bound/udp.rs +++ b/kernel/libs/aster-bigtcp/src/socket/bound/udp.rs @@ -62,7 +62,7 @@ impl UdpSocketBg { udp_payload, ); - self.add_events(SocketEvents::CAN_RECV); + self.notify_events(SocketEvents::CAN_RECV); true } @@ -82,7 +82,7 @@ impl UdpSocketBg { .unwrap(); // For UDP, dequeuing a packet means that we can queue more packets. - self.add_events(SocketEvents::CAN_SEND); + self.notify_events(SocketEvents::CAN_SEND); self.inner .need_dispatch diff --git a/kernel/libs/aster-bigtcp/src/socket_table.rs b/kernel/libs/aster-bigtcp/src/socket_table.rs index 52c63aa9..c8129fad 100644 --- a/kernel/libs/aster-bigtcp/src/socket_table.rs +++ b/kernel/libs/aster-bigtcp/src/socket_table.rs @@ -295,7 +295,7 @@ impl SocketTable { "there should be no need to poll a dead TCP connection", ); - connection.on_dead_events(); + connection.notify_dead_events(); } pub(crate) fn remove_udp_socket( @@ -309,18 +309,6 @@ impl SocketTable { Some(self.udp_sockets.swap_remove(index)) } - pub(crate) fn tcp_listener_iter(&self) -> impl Iterator>> { - self.listener_buckets - .iter() - .flat_map(|bucket| bucket.listeners.iter()) - } - - pub(crate) fn tcp_conn_iter(&self) -> impl Iterator>> { - self.connection_buckets - .iter() - .flat_map(|bucket| bucket.connections.iter()) - } - pub(crate) fn udp_socket_iter(&self) -> impl Iterator>> { self.udp_sockets.iter() }