Use IoVec-based reader/writer to refactor network APIs

This commit is contained in:
Jianfeng Jiang
2024-09-11 02:36:24 +00:00
committed by Tate, Hongliang Tian
parent ea8327af0f
commit 985813c7f9
24 changed files with 484 additions and 453 deletions

View File

@ -16,6 +16,7 @@ use crate::{
},
prelude::*,
process::signal::Pollee,
util::{MultiRead, MultiWrite},
};
pub struct ConnectedStream {
@ -55,14 +56,20 @@ impl ConnectedStream {
Ok(())
}
pub fn try_recv(&self, buf: &mut [u8], _flags: SendRecvFlags) -> Result<usize> {
let result = self
.bound_socket
.raw_with(|socket: &mut RawTcpSocket| socket.recv_slice(buf));
pub fn try_recv(&self, writer: &mut dyn MultiWrite, _flags: SendRecvFlags) -> Result<usize> {
let result = self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
socket.recv(
|socket_buffer| match writer.write(&mut VmReader::from(&*socket_buffer)) {
Ok(len) => (len, Ok(len)),
Err(e) => (0, Err(e)),
},
)
});
match result {
Ok(0) => return_errno_with_message!(Errno::EAGAIN, "the receive buffer is empty"),
Ok(recv_bytes) => Ok(recv_bytes),
Ok(Ok(0)) => return_errno_with_message!(Errno::EAGAIN, "the receive buffer is empty"),
Ok(Ok(recv_bytes)) => Ok(recv_bytes),
Ok(Err(e)) => Err(e),
Err(RecvError::Finished) => Ok(0),
Err(RecvError::InvalidState) => {
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset")
@ -70,14 +77,20 @@ impl ConnectedStream {
}
}
pub fn try_send(&self, buf: &[u8], _flags: SendRecvFlags) -> Result<usize> {
let result = self
.bound_socket
.raw_with(|socket: &mut RawTcpSocket| socket.send_slice(buf));
pub fn try_send(&self, reader: &mut dyn MultiRead, _flags: SendRecvFlags) -> Result<usize> {
let result = self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
socket.send(
|socket_buffer| match reader.read(&mut VmWriter::from(socket_buffer)) {
Ok(len) => (len, Ok(len)),
Err(e) => (0, Err(e)),
},
)
});
match result {
Ok(0) => return_errno_with_message!(Errno::EAGAIN, "the send buffer is full"),
Ok(sent_bytes) => Ok(sent_bytes),
Ok(Ok(0)) => return_errno_with_message!(Errno::EAGAIN, "the send buffer is full"),
Ok(Ok(sent_bytes)) => Ok(sent_bytes),
Ok(Err(e)) => Err(e),
Err(SendError::InvalidState) => {
// FIXME: `EPIPE` is another possibility, which means that the socket is shut down
// for writing. In that case, we should also trigger a `SIGPIPE` if `MSG_NOSIGNAL`