mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Simplify the TCP state check
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
9edee83ef1
commit
eef56c770b
@ -11,6 +11,8 @@ pub use poll::lazy_init;
|
||||
pub type Iface = dyn aster_bigtcp::iface::Iface<ext::BigtcpExt>;
|
||||
pub type BoundPort = aster_bigtcp::iface::BoundPort<ext::BigtcpExt>;
|
||||
|
||||
pub type RawTcpSocketExt = aster_bigtcp::socket::RawTcpSocketExt<ext::BigtcpExt>;
|
||||
|
||||
pub type TcpConnection = aster_bigtcp::socket::TcpConnection<ext::BigtcpExt>;
|
||||
pub type TcpListener = aster_bigtcp::socket::TcpListener<ext::BigtcpExt>;
|
||||
pub type UdpSocket = aster_bigtcp::socket::UdpSocket<ext::BigtcpExt>;
|
||||
|
@ -4,7 +4,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use aster_bigtcp::{
|
||||
errors::tcp::{RecvError, SendError},
|
||||
socket::{NeedIfacePoll, RawTcpSetOption, RawTcpSocket, TcpStateCheck},
|
||||
socket::{NeedIfacePoll, RawTcpSetOption},
|
||||
wire::IpEndpoint,
|
||||
};
|
||||
|
||||
@ -12,7 +12,7 @@ use super::StreamObserver;
|
||||
use crate::{
|
||||
events::IoEvents,
|
||||
net::{
|
||||
iface::{Iface, TcpConnection},
|
||||
iface::{Iface, RawTcpSocketExt, TcpConnection},
|
||||
socket::util::{send_recv_flags::SendRecvFlags, shutdown_cmd::SockShutdownCmd},
|
||||
},
|
||||
prelude::*,
|
||||
@ -34,15 +34,8 @@ pub struct ConnectedStream {
|
||||
/// connection is established asynchronously will succeed and any subsequent `connect()` will
|
||||
/// fail.
|
||||
is_new_connection: bool,
|
||||
/// Indicates if the receiving side of this socket is closed.
|
||||
///
|
||||
/// The receiving side may be closed if this side disables reading
|
||||
/// or if the peer side closes its sending half.
|
||||
is_receiving_closed: AtomicBool,
|
||||
/// Indicates if the sending side of this socket is closed.
|
||||
///
|
||||
/// The sending side can only be closed if this side disables writing.
|
||||
is_sending_closed: AtomicBool,
|
||||
/// Indicates if the receiving side of this socket is shut down by the user.
|
||||
is_receiving_shut: AtomicBool,
|
||||
}
|
||||
|
||||
impl ConnectedStream {
|
||||
@ -55,8 +48,7 @@ impl ConnectedStream {
|
||||
tcp_conn,
|
||||
remote_endpoint,
|
||||
is_new_connection,
|
||||
is_receiving_closed: AtomicBool::new(false),
|
||||
is_sending_closed: AtomicBool::new(false),
|
||||
is_receiving_shut: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,12 +56,11 @@ impl ConnectedStream {
|
||||
let mut events = IoEvents::empty();
|
||||
|
||||
if cmd.shut_read() {
|
||||
self.is_receiving_closed.store(true, Ordering::Relaxed);
|
||||
self.is_receiving_shut.store(true, Ordering::Relaxed);
|
||||
events |= IoEvents::IN | IoEvents::RDHUP;
|
||||
}
|
||||
|
||||
if cmd.shut_write() {
|
||||
self.is_sending_closed.store(true, Ordering::Relaxed);
|
||||
if !self.tcp_conn.close() {
|
||||
return_errno_with_message!(Errno::ENOTCONN, "the socket is not connected");
|
||||
}
|
||||
@ -94,7 +85,7 @@ impl ConnectedStream {
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok((Ok(0), need_poll)) if self.is_receiving_closed.load(Ordering::Relaxed) => {
|
||||
Ok((Ok(0), need_poll)) if self.is_receiving_shut.load(Ordering::Relaxed) => {
|
||||
Ok((0, need_poll))
|
||||
}
|
||||
Ok((Ok(0), need_poll)) => {
|
||||
@ -175,17 +166,9 @@ impl ConnectedStream {
|
||||
|
||||
pub(super) fn check_io_events(&self) -> IoEvents {
|
||||
self.tcp_conn.raw_with(|socket| {
|
||||
if socket.is_peer_closed() {
|
||||
// Only the sending side of peer socket is closed
|
||||
self.is_receiving_closed.store(true, Ordering::Relaxed);
|
||||
} else if socket.is_closed() {
|
||||
// The sending side of both peer socket and this socket are closed
|
||||
self.is_receiving_closed.store(true, Ordering::Relaxed);
|
||||
self.is_sending_closed.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
let is_receiving_closed = self.is_receiving_closed.load(Ordering::Relaxed);
|
||||
let is_sending_closed = self.is_sending_closed.load(Ordering::Relaxed);
|
||||
let is_receiving_closed =
|
||||
self.is_receiving_shut.load(Ordering::Relaxed) || !socket.may_recv_new();
|
||||
let is_sending_closed = !socket.may_send();
|
||||
|
||||
let mut events = IoEvents::empty();
|
||||
|
||||
@ -219,7 +202,7 @@ impl ConnectedStream {
|
||||
set_option(&self.tcp_conn)
|
||||
}
|
||||
|
||||
pub(super) fn raw_with<R>(&self, f: impl FnOnce(&RawTcpSocket) -> R) -> R {
|
||||
pub(super) fn raw_with<R>(&self, f: impl FnOnce(&RawTcpSocketExt) -> R) -> R {
|
||||
self.tcp_conn.raw_with(f)
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,18 @@ impl SocketEventObserver for StreamObserver {
|
||||
io_events |= IoEvents::OUT;
|
||||
}
|
||||
|
||||
if events.contains(SocketEvents::PEER_CLOSED) {
|
||||
if events.contains(SocketEvents::CLOSED_RECV) {
|
||||
// `CLOSED_RECV` definitely causes IN and RDHUP.
|
||||
io_events |= IoEvents::IN | IoEvents::RDHUP;
|
||||
// `CLOSED_RECV` may cause HUP/ERR (combined with a previous `CLOSED_SEND`).
|
||||
io_events |= IoEvents::HUP | IoEvents::ERR;
|
||||
}
|
||||
|
||||
if events.contains(SocketEvents::CLOSED) {
|
||||
io_events |= IoEvents::IN | IoEvents::OUT;
|
||||
io_events |= IoEvents::RDHUP | IoEvents::HUP | IoEvents::ERR;
|
||||
if events.contains(SocketEvents::CLOSED_SEND) {
|
||||
// `CLOSED_SEND` definitely causes OUT.
|
||||
io_events |= IoEvents::OUT;
|
||||
// `CLOSED_SEND` may cause HUP/ERR (combined with a previous `CLOSED_RECV`).
|
||||
io_events |= IoEvents::HUP | IoEvents::ERR;
|
||||
}
|
||||
|
||||
self.0.notify(io_events);
|
||||
|
Reference in New Issue
Block a user