mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-21 08:26:30 +00:00
Notify socket events directly
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
2f66f5d234
commit
d9f3a7761a
@ -202,23 +202,6 @@ impl<E: Ext> IfaceCommon<E> {
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
@ -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<T: Inner<E>, E: Ext> {
|
||||
pub(super) bound: BoundPort<E>,
|
||||
pub(super) inner: T,
|
||||
observer: Once<T::Observer>,
|
||||
events: AtomicU8,
|
||||
}
|
||||
|
||||
impl<T: Inner<E>, E: Ext> Drop for Socket<T, E> {
|
||||
@ -62,7 +60,6 @@ impl<T: Inner<E>, E: Ext> Socket<T, E> {
|
||||
bound,
|
||||
inner,
|
||||
observer: Once::new(),
|
||||
events: AtomicU8::new(0),
|
||||
})))
|
||||
}
|
||||
|
||||
@ -74,7 +71,6 @@ impl<T: Inner<E>, E: Ext> Socket<T, E> {
|
||||
bound,
|
||||
inner: inner_fn(weak),
|
||||
observer: Once::new(),
|
||||
events: AtomicU8::new(0),
|
||||
})))
|
||||
}
|
||||
|
||||
@ -110,44 +106,24 @@ define_boolean_value!(
|
||||
);
|
||||
|
||||
impl<T: Inner<E>, E: Ext> SocketBg<T, E> {
|
||||
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<Self>)
|
||||
pub(crate) fn notify_dead_events(self: Arc<Self>)
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ impl<E: Ext> RawTcpSocketExt<E> {
|
||||
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<E: Ext> TcpConnectionBg<E> {
|
||||
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<E: Ext> TcpConnectionBg<E> {
|
||||
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);
|
||||
|
@ -62,7 +62,7 @@ impl<E: Ext> UdpSocketBg<E> {
|
||||
udp_payload,
|
||||
);
|
||||
|
||||
self.add_events(SocketEvents::CAN_RECV);
|
||||
self.notify_events(SocketEvents::CAN_RECV);
|
||||
|
||||
true
|
||||
}
|
||||
@ -82,7 +82,7 @@ impl<E: Ext> UdpSocketBg<E> {
|
||||
.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
|
||||
|
@ -295,7 +295,7 @@ impl<E: Ext> SocketTable<E> {
|
||||
"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<E: Ext> SocketTable<E> {
|
||||
Some(self.udp_sockets.swap_remove(index))
|
||||
}
|
||||
|
||||
pub(crate) fn tcp_listener_iter(&self) -> impl Iterator<Item = &Arc<TcpListenerBg<E>>> {
|
||||
self.listener_buckets
|
||||
.iter()
|
||||
.flat_map(|bucket| bucket.listeners.iter())
|
||||
}
|
||||
|
||||
pub(crate) fn tcp_conn_iter(&self) -> impl Iterator<Item = &Arc<TcpConnectionBg<E>>> {
|
||||
self.connection_buckets
|
||||
.iter()
|
||||
.flat_map(|bucket| bucket.connections.iter())
|
||||
}
|
||||
|
||||
pub(crate) fn udp_socket_iter(&self) -> impl Iterator<Item = &Arc<UdpSocketBg<E>>> {
|
||||
self.udp_sockets.iter()
|
||||
}
|
||||
|
Reference in New Issue
Block a user