mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 04:13:24 +00:00
Optimize vsock code structure
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
60dd17fdd3
commit
646406115e
@ -33,7 +33,7 @@ impl Connected {
|
||||
|
||||
pub fn from_connecting(connecting: Arc<Connecting>) -> Self {
|
||||
Self {
|
||||
connection: SpinLock::new(Connection::from_info(connecting.info())),
|
||||
connection: SpinLock::new(Connection::new_from_info(connecting.info())),
|
||||
id: connecting.id(),
|
||||
pollee: Pollee::new(IoEvents::empty()),
|
||||
}
|
||||
@ -58,7 +58,7 @@ impl Connected {
|
||||
|
||||
match bytes_read {
|
||||
0 => {
|
||||
if !connection.peer_requested_shutdown {
|
||||
if !connection.is_peer_requested_shutdown() {
|
||||
return_errno_with_message!(Errno::EAGAIN, "the receive buffer is empty");
|
||||
} else {
|
||||
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset");
|
||||
@ -84,17 +84,26 @@ impl Connected {
|
||||
let connection = self.connection.lock_irq_disabled();
|
||||
// If buffer is now empty and the peer requested shutdown, finish shutting down the
|
||||
// connection.
|
||||
connection.peer_requested_shutdown && connection.buffer.is_empty()
|
||||
connection.is_peer_requested_shutdown() && connection.buffer.is_empty()
|
||||
}
|
||||
|
||||
pub fn is_closed(&self) -> bool {
|
||||
let connection = self.connection.lock_irq_disabled();
|
||||
connection.is_local_shutdown()
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, cmd: SockShutdownCmd) -> Result<()> {
|
||||
// TODO: deal with cmd
|
||||
if self.should_close() {
|
||||
let connection = self.connection.lock_irq_disabled();
|
||||
let mut connection = self.connection.lock_irq_disabled();
|
||||
if connection.is_local_shutdown() {
|
||||
return Ok(());
|
||||
}
|
||||
let vsockspace = VSOCK_GLOBAL.get().unwrap();
|
||||
vsockspace.reset(&connection.info).unwrap();
|
||||
vsockspace.remove_connected_socket(&self.id());
|
||||
vsockspace.recycle_port(&self.local_addr().port);
|
||||
connection.set_local_shutdown();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -113,8 +122,10 @@ impl Connected {
|
||||
connection.add(bytes)
|
||||
}
|
||||
|
||||
pub fn peer_requested_shutdown(&self) {
|
||||
self.connection.lock_irq_disabled().peer_requested_shutdown = true
|
||||
pub fn set_peer_requested_shutdown(&self) {
|
||||
self.connection
|
||||
.lock_irq_disabled()
|
||||
.set_peer_requested_shutdown()
|
||||
}
|
||||
|
||||
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
@ -134,41 +145,69 @@ impl Connected {
|
||||
|
||||
impl Drop for Connected {
|
||||
fn drop(&mut self) {
|
||||
let connection = self.connection.lock_irq_disabled();
|
||||
if connection.is_local_shutdown() {
|
||||
return;
|
||||
}
|
||||
let vsockspace = VSOCK_GLOBAL.get().unwrap();
|
||||
vsockspace.reset(&connection.info).unwrap();
|
||||
vsockspace.remove_connected_socket(&self.id());
|
||||
vsockspace.recycle_port(&self.local_addr().port);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Connection {
|
||||
struct Connection {
|
||||
info: ConnectionInfo,
|
||||
buffer: HeapRb<u8>,
|
||||
/// The peer sent a SHUTDOWN request, but we haven't yet responded with a RST because there is
|
||||
/// still data in the buffer.
|
||||
pub peer_requested_shutdown: bool,
|
||||
peer_requested_shutdown: bool,
|
||||
local_shutdown: bool,
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
pub fn new(peer: VsockSocketAddr, local_port: u32) -> Self {
|
||||
fn new(peer: VsockSocketAddr, local_port: u32) -> Self {
|
||||
let mut info = ConnectionInfo::new(peer.into(), local_port);
|
||||
info.buf_alloc = PER_CONNECTION_BUFFER_CAPACITY.try_into().unwrap();
|
||||
Self {
|
||||
info,
|
||||
buffer: HeapRb::new(PER_CONNECTION_BUFFER_CAPACITY),
|
||||
peer_requested_shutdown: false,
|
||||
local_shutdown: false,
|
||||
}
|
||||
}
|
||||
pub fn from_info(mut info: ConnectionInfo) -> Self {
|
||||
|
||||
fn is_peer_requested_shutdown(&self) -> bool {
|
||||
self.peer_requested_shutdown
|
||||
}
|
||||
|
||||
fn set_peer_requested_shutdown(&mut self) {
|
||||
self.peer_requested_shutdown = true
|
||||
}
|
||||
|
||||
fn is_local_shutdown(&self) -> bool {
|
||||
self.local_shutdown
|
||||
}
|
||||
|
||||
fn set_local_shutdown(&mut self) {
|
||||
self.local_shutdown = true
|
||||
}
|
||||
|
||||
fn new_from_info(mut info: ConnectionInfo) -> Self {
|
||||
info.buf_alloc = PER_CONNECTION_BUFFER_CAPACITY.try_into().unwrap();
|
||||
Self {
|
||||
info,
|
||||
buffer: HeapRb::new(PER_CONNECTION_BUFFER_CAPACITY),
|
||||
peer_requested_shutdown: false,
|
||||
local_shutdown: false,
|
||||
}
|
||||
}
|
||||
pub fn update_for_event(&mut self, event: &VsockEvent) {
|
||||
|
||||
fn update_for_event(&mut self, event: &VsockEvent) {
|
||||
self.info.update_for_event(event)
|
||||
}
|
||||
pub fn add(&mut self, bytes: &[u8]) -> bool {
|
||||
|
||||
fn add(&mut self, bytes: &[u8]) -> bool {
|
||||
if bytes.len() > self.buffer.free_len() {
|
||||
return false;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ impl Connecting {
|
||||
pollee: Pollee::new(IoEvents::empty()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> VsockSocketAddr {
|
||||
self.id.peer_addr
|
||||
}
|
||||
@ -35,15 +36,19 @@ impl Connecting {
|
||||
pub fn id(&self) -> ConnectionID {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn info(&self) -> ConnectionInfo {
|
||||
self.info.lock_irq_disabled().clone()
|
||||
}
|
||||
|
||||
pub fn update_info(&self, event: &VsockEvent) {
|
||||
self.info.lock_irq_disabled().update_for_event(event)
|
||||
}
|
||||
|
||||
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
self.pollee.poll(mask, poller)
|
||||
}
|
||||
|
||||
pub fn add_events(&self, events: IoEvents) {
|
||||
self.pollee.add_events(events)
|
||||
}
|
||||
@ -53,5 +58,6 @@ impl Drop for Connecting {
|
||||
fn drop(&mut self) {
|
||||
let vsockspace = VSOCK_GLOBAL.get().unwrap();
|
||||
vsockspace.recycle_port(&self.local_addr().port);
|
||||
vsockspace.remove_connecting_socket(&self.local_addr());
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ impl Init {
|
||||
} else {
|
||||
return_errno_with_message!(Errno::EAGAIN, "cannot find unused high port");
|
||||
}
|
||||
} else if !vsockspace.insert_port(new_addr.port) {
|
||||
} else if !vsockspace.bind_port(new_addr.port) {
|
||||
return_errno_with_message!(Errno::EADDRNOTAVAIL, "the port in address is occupied");
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ impl Listen {
|
||||
pub fn addr(&self) -> VsockSocketAddr {
|
||||
self.addr
|
||||
}
|
||||
|
||||
pub fn push_incoming(&self, connect: Arc<Connected>) -> Result<()> {
|
||||
let mut incoming_connections = self.incoming_connection.lock_irq_disabled();
|
||||
if incoming_connections.len() >= self.backlog {
|
||||
@ -47,13 +48,14 @@ impl Listen {
|
||||
|
||||
Ok(connection)
|
||||
}
|
||||
|
||||
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
self.pollee.poll(mask, poller)
|
||||
}
|
||||
|
||||
pub fn update_io_events(&self) {
|
||||
let can_accept = !self.incoming_connection.lock_irq_disabled().is_empty();
|
||||
if can_accept {
|
||||
let incomming_connection = self.incoming_connection.lock_irq_disabled();
|
||||
if !incomming_connection.is_empty() {
|
||||
self.pollee.add_events(IoEvents::IN);
|
||||
} else {
|
||||
self.pollee.del_events(IoEvents::IN);
|
||||
@ -63,6 +65,8 @@ impl Listen {
|
||||
|
||||
impl Drop for Listen {
|
||||
fn drop(&mut self) {
|
||||
VSOCK_GLOBAL.get().unwrap().recycle_port(&self.addr.port);
|
||||
let vsockspace = VSOCK_GLOBAL.get().unwrap();
|
||||
vsockspace.recycle_port(&self.addr.port);
|
||||
vsockspace.remove_listen_socket(&self.addr);
|
||||
}
|
||||
}
|
||||
|
@ -35,12 +35,14 @@ impl VsockStreamSocket {
|
||||
is_nonblocking: AtomicBool::new(nonblocking),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn new_from_connected(connected: Arc<Connected>) -> Self {
|
||||
Self {
|
||||
status: RwLock::new(Status::Connected(connected)),
|
||||
is_nonblocking: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_nonblocking(&self) -> bool {
|
||||
self.is_nonblocking.load(Ordering::Relaxed)
|
||||
}
|
||||
@ -103,7 +105,8 @@ impl VsockStreamSocket {
|
||||
VSOCK_GLOBAL
|
||||
.get()
|
||||
.unwrap()
|
||||
.response(&connected.get_info())?;
|
||||
.response(&connected.get_info())
|
||||
.unwrap();
|
||||
|
||||
let socket = Arc::new(VsockStreamSocket::new_from_connected(connected));
|
||||
Ok((socket, peer_addr.into()))
|
||||
@ -123,7 +126,6 @@ impl VsockStreamSocket {
|
||||
let peer_addr = self.peer_addr()?;
|
||||
// If buffer is now empty and the peer requested shutdown, finish shutting down the
|
||||
// connection.
|
||||
// TODO: properly place the close request
|
||||
if connected.should_close() {
|
||||
if let Err(e) = self.shutdown(SockShutdownCmd::SHUT_RDWR) {
|
||||
debug!("The error is {:?}", e);
|
||||
@ -189,7 +191,7 @@ impl Socket for VsockStreamSocket {
|
||||
}
|
||||
|
||||
// Since blocking mode is supported, there is no need to store the connecting status.
|
||||
// TODO: Refactor when blocking mode is supported.
|
||||
// TODO: Refactor when nonblocking mode is supported.
|
||||
fn connect(&self, sockaddr: SocketAddr) -> Result<()> {
|
||||
let init = match &*self.status.read() {
|
||||
Status::Init(init) => init.clone(),
|
||||
@ -223,7 +225,12 @@ impl Socket for VsockStreamSocket {
|
||||
.poll(IoEvents::IN, Some(&poller))
|
||||
.contains(IoEvents::IN)
|
||||
{
|
||||
poller.wait()?;
|
||||
if let Err(e) = poller.wait() {
|
||||
vsockspace
|
||||
.remove_connecting_socket(&connecting.local_addr())
|
||||
.unwrap();
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
|
||||
vsockspace
|
||||
|
Reference in New Issue
Block a user