mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Remove Arc
s in TCP and UDP states
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
07e8cfe2e7
commit
a10d04c5f9
@ -1,116 +1,77 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use super::{connected::ConnectedStream, init::InitStream};
|
||||
use crate::{
|
||||
events::{IoEvents, Observer},
|
||||
net::{
|
||||
iface::{AnyBoundSocket, IpEndpoint, RawTcpSocket},
|
||||
poll_ifaces,
|
||||
},
|
||||
events::IoEvents,
|
||||
net::iface::{AnyBoundSocket, IpEndpoint, RawTcpSocket},
|
||||
prelude::*,
|
||||
process::signal::{Pollee, Poller},
|
||||
process::signal::Pollee,
|
||||
};
|
||||
|
||||
pub struct ConnectingStream {
|
||||
nonblocking: AtomicBool,
|
||||
bound_socket: Arc<AnyBoundSocket>,
|
||||
remote_endpoint: IpEndpoint,
|
||||
conn_result: RwLock<Option<ConnResult>>,
|
||||
pollee: Pollee,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum ConnResult {
|
||||
Connected,
|
||||
Refused,
|
||||
}
|
||||
|
||||
pub enum NonConnectedStream {
|
||||
Init(InitStream),
|
||||
Connecting(ConnectingStream),
|
||||
}
|
||||
|
||||
impl ConnectingStream {
|
||||
pub fn new(
|
||||
nonblocking: bool,
|
||||
bound_socket: Arc<AnyBoundSocket>,
|
||||
remote_endpoint: IpEndpoint,
|
||||
pollee: Pollee,
|
||||
) -> Result<Arc<Self>> {
|
||||
bound_socket.do_connect(remote_endpoint)?;
|
||||
|
||||
let connecting = Arc::new(Self {
|
||||
nonblocking: AtomicBool::new(nonblocking),
|
||||
) -> core::result::Result<Self, (Error, Arc<AnyBoundSocket>)> {
|
||||
if let Err(err) = bound_socket.do_connect(remote_endpoint) {
|
||||
return Err((err, bound_socket));
|
||||
}
|
||||
Ok(Self {
|
||||
bound_socket,
|
||||
remote_endpoint,
|
||||
conn_result: RwLock::new(None),
|
||||
pollee,
|
||||
});
|
||||
connecting.pollee.reset_events();
|
||||
connecting
|
||||
.bound_socket
|
||||
.set_observer(Arc::downgrade(&connecting) as _);
|
||||
Ok(connecting)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn wait_conn(
|
||||
&self,
|
||||
) -> core::result::Result<Arc<ConnectedStream>, (Error, Arc<InitStream>)> {
|
||||
debug_assert!(!self.is_nonblocking());
|
||||
|
||||
let poller = Poller::new();
|
||||
loop {
|
||||
poll_ifaces();
|
||||
|
||||
match *self.conn_result.read() {
|
||||
Some(ConnResult::Connected) => {
|
||||
return Ok(ConnectedStream::new(
|
||||
self.is_nonblocking(),
|
||||
self.bound_socket.clone(),
|
||||
self.remote_endpoint,
|
||||
self.pollee.clone(),
|
||||
));
|
||||
}
|
||||
Some(ConnResult::Refused) => {
|
||||
return Err((
|
||||
Error::with_message(Errno::ECONNREFUSED, "connection refused"),
|
||||
InitStream::new_bound(
|
||||
self.is_nonblocking(),
|
||||
self.bound_socket.clone(),
|
||||
self.pollee.clone(),
|
||||
),
|
||||
));
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
|
||||
let events = self.poll(IoEvents::OUT, Some(&poller));
|
||||
if !events.contains(IoEvents::OUT) {
|
||||
// FIXME: deal with nonblocking mode & connecting timeout
|
||||
poller.wait().expect("async connect() not implemented");
|
||||
}
|
||||
pub fn into_result(self) -> core::result::Result<ConnectedStream, (Error, NonConnectedStream)> {
|
||||
let conn_result = *self.conn_result.read();
|
||||
match conn_result {
|
||||
Some(ConnResult::Connected) => Ok(ConnectedStream::new(
|
||||
self.bound_socket,
|
||||
self.remote_endpoint,
|
||||
)),
|
||||
Some(ConnResult::Refused) => Err((
|
||||
Error::with_message(Errno::ECONNREFUSED, "the connection is refused"),
|
||||
NonConnectedStream::Init(InitStream::new_bound(self.bound_socket)),
|
||||
)),
|
||||
None => Err((
|
||||
Error::with_message(Errno::EAGAIN, "the connection is pending"),
|
||||
NonConnectedStream::Connecting(self),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_endpoint(&self) -> Result<IpEndpoint> {
|
||||
self.bound_socket
|
||||
.local_endpoint()
|
||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "no local endpoint"))
|
||||
pub fn local_endpoint(&self) -> IpEndpoint {
|
||||
self.bound_socket.local_endpoint().unwrap()
|
||||
}
|
||||
|
||||
pub fn remote_endpoint(&self) -> Result<IpEndpoint> {
|
||||
Ok(self.remote_endpoint)
|
||||
pub fn remote_endpoint(&self) -> IpEndpoint {
|
||||
self.remote_endpoint
|
||||
}
|
||||
|
||||
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
self.pollee.poll(mask, poller)
|
||||
pub(super) fn init_pollee(&self, pollee: &Pollee) {
|
||||
pollee.reset_events();
|
||||
self.update_io_events(pollee);
|
||||
}
|
||||
|
||||
pub fn is_nonblocking(&self) -> bool {
|
||||
self.nonblocking.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) {
|
||||
self.nonblocking.store(nonblocking, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
fn update_io_events(&self) {
|
||||
pub(super) fn update_io_events(&self, pollee: &Pollee) {
|
||||
if self.conn_result.read().is_some() {
|
||||
return;
|
||||
}
|
||||
@ -143,13 +104,7 @@ impl ConnectingStream {
|
||||
// be responsible to initialize all the I/O events including `IoEvents::OUT`, so the
|
||||
// following hard-coded event addition can be removed.
|
||||
if became_writable {
|
||||
self.pollee.add_events(IoEvents::OUT);
|
||||
pollee.add_events(IoEvents::OUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Observer<()> for ConnectingStream {
|
||||
fn on_events(&self, _: &()) {
|
||||
self.update_io_events();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user