add docs and delete deprecated options and methods (about control) in `socket`

This commit is contained in:
xxchan 2020-08-01 21:27:20 +08:00
parent 745a53b903
commit 590131ee7b
2 changed files with 72 additions and 98 deletions

View File

@ -2,7 +2,6 @@ use {
crate::object::*, crate::object::*,
alloc::collections::VecDeque, alloc::collections::VecDeque,
alloc::sync::{Arc, Weak}, alloc::sync::{Arc, Weak},
alloc::vec::Vec,
bitflags::bitflags, bitflags::bitflags,
spin::Mutex, spin::Mutex,
}; };
@ -22,7 +21,6 @@ pub struct Socket {
#[derive(Default)] #[derive(Default)]
struct SocketInner { struct SocketInner {
control_msg: Vec<u8>,
data: VecDeque<u8>, data: VecDeque<u8>,
datagram_len: VecDeque<usize>, datagram_len: VecDeque<usize>,
read_threshold: usize, read_threshold: usize,
@ -48,21 +46,25 @@ bitflags! {
pub struct SocketFlags: u32 { pub struct SocketFlags: u32 {
#[allow(clippy::identity_op)] #[allow(clippy::identity_op)]
// These options can be passed to socket_shutdown(). // These options can be passed to socket_shutdown().
/// Via this option to `socket_shutdown()`, one end of the socket can be closed for writing.
const SHUTDOWN_WRITE = 1; const SHUTDOWN_WRITE = 1;
/// Via this option to `socket_shutdown()`, one end of the socket can be closed for reading.
const SHUTDOWN_READ = 1 << 1; const SHUTDOWN_READ = 1 << 1;
/// Valid flags of `socket_shutdown()`.
const SHUTDOWN_MASK = Self::SHUTDOWN_WRITE.bits | Self::SHUTDOWN_READ.bits; const SHUTDOWN_MASK = Self::SHUTDOWN_WRITE.bits | Self::SHUTDOWN_READ.bits;
// These can be passed to socket_create(). // These can be passed to socket_create().
// const STREAM = 0; // Don't use contains // const STREAM = 0; // Don't use contains
/// Create a datagram socket. See [`read`] and [`write`] for details.
///
/// [`read`]: struct.Socket.html#method.read
/// [`write`]: struct.Socket.html#method.write
const DATAGRAM = 1; const DATAGRAM = 1;
const HAS_CONTROL = 1 << 1; /// Valid flags of `socket_create()`.
const HAS_ACCEPT = 1 << 2; const CREATE_MASK = Self::DATAGRAM.bits;
const CREATE_MASK = Self::DATAGRAM.bits | Self::HAS_CONTROL.bits | Self::HAS_ACCEPT.bits;
// These can be passed to socket_read() and socket_write().
const SOCKET_CONTROL = 1 << 2;
// These can be passed to socket_read(). // These can be passed to socket_read().
/// Leave the message in the socket.
const SOCKET_PEEK = 1 << 3; const SOCKET_PEEK = 1 << 3;
} }
} }
@ -75,13 +77,13 @@ impl Socket {
if !(flags - SocketFlags::CREATE_MASK).is_empty() { if !(flags - SocketFlags::CREATE_MASK).is_empty() {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
} }
let mut starting_signals: Signal = Signal::WRITABLE; let starting_signals: Signal = Signal::WRITABLE;
if flags.contains(SocketFlags::HAS_ACCEPT) { // if flags.contains(SocketFlags::HAS_ACCEPT) {
starting_signals |= Signal::SOCKET_SHARE; // starting_signals |= Signal::SOCKET_SHARE;
} // }
if flags.contains(SocketFlags::HAS_CONTROL) { // if flags.contains(SocketFlags::HAS_CONTROL) {
starting_signals |= Signal::SOCKET_CONTROL_WRITABLE; // starting_signals |= Signal::SOCKET_CONTROL_WRITABLE;
} // }
let mut end0 = Arc::new(Socket { let mut end0 = Arc::new(Socket {
base: KObjectBase::with_signal(starting_signals), base: KObjectBase::with_signal(starting_signals),
peer: Weak::default(), peer: Weak::default(),
@ -101,23 +103,18 @@ impl Socket {
Ok((end0, end1)) Ok((end0, end1))
} }
/// Write data to the socket. /// Write data to the socket. If successful, the number of bytes actually written are returned.
pub fn write(&self, options: SocketFlags, data: &[u8]) -> ZxResult<usize> { ///
if options.contains(SocketFlags::SOCKET_CONTROL) { /// A **SOCKET_STREAM**(default) socket write can be short if the socket does not have
if !self.flags.contains(SocketFlags::HAS_CONTROL) { /// enough space for all of *data*.
return Err(ZxError::BAD_STATE); /// Otherwise, if the socket was already full, the call returns **ZxError::SHOULD_WAIT**.
} ///
if data.is_empty() { ///
return Err(ZxError::INVALID_ARGS); /// A **SOCKET_DATAGRAM** socket write is never short. If the socket has
} /// insufficient space for *data*, it writes nothing and returns
if data.len() > 1024 { /// **ZxError::SHOULD_WAIT**. Attempting to write a packet larger than the datagram socket's
return Err(ZxError::OUT_OF_RANGE); /// capacity will fail with **ZxError::OUT_OF_RANGE**.
} pub fn write(&self, data: &[u8]) -> ZxResult<usize> {
let peer = self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)?;
let actual_count = peer.write_control(data)?;
self.base.signal_clear(Signal::SOCKET_CONTROL_WRITABLE);
Ok(actual_count)
} else {
if self.base.signal().contains(Signal::SOCKET_WRITE_DISABLED) { if self.base.signal().contains(Signal::SOCKET_WRITE_DISABLED) {
return Err(ZxError::BAD_STATE); return Err(ZxError::BAD_STATE);
} }
@ -138,18 +135,6 @@ impl Socket {
} }
Ok(actual_count) Ok(actual_count)
} }
}
fn write_control(&self, data: &[u8]) -> ZxResult<usize> {
let mut inner = self.inner.lock();
if !inner.control_msg.is_empty() {
return Err(ZxError::SHOULD_WAIT);
}
let actual_count = data.len();
inner.control_msg.extend_from_slice(data);
self.base.signal_set(Signal::SOCKET_CONTROL_READABLE);
Ok(actual_count)
}
fn write_data(&self, data: &[u8]) -> ZxResult<usize> { fn write_data(&self, data: &[u8]) -> ZxResult<usize> {
let data_len = self.inner.lock().data.len(); let data_len = self.inner.lock().data.len();
@ -199,41 +184,17 @@ impl Socket {
Ok(actual_count) Ok(actual_count)
} }
/// Read data from the socket. /// Read data from the socket. If successful, the number of bytes actually read are returned.
///
/// If the socket was created with **SOCKET_DATAGRAM**, this method reads
/// only the first available datagram in the socket (if one is present).
/// If *data* is too small for the datagram, then the read will be
/// truncated, and any remaining bytes in the datagram will be discarded.
///
/// Supported *options* are:
///
/// * **SOCKET_PEEK** to leave the message in the socket.
pub fn read(&self, options: SocketFlags, data: &mut [u8]) -> ZxResult<usize> { pub fn read(&self, options: SocketFlags, data: &mut [u8]) -> ZxResult<usize> {
if options.contains(SocketFlags::SOCKET_CONTROL) {
if !self.flags.contains(SocketFlags::HAS_CONTROL) {
return Err(ZxError::BAD_STATE);
}
self.read_control(options, data)
} else {
self.read_data(options, data)
}
}
fn read_control(&self, options: SocketFlags, data: &mut [u8]) -> ZxResult<usize> {
let mut inner = self.inner.lock();
if inner.control_msg.is_empty() {
return Err(ZxError::SHOULD_WAIT);
}
let read_size = data.len().min(inner.control_msg.len());
if options.contains(SocketFlags::SOCKET_PEEK) {
for (i, x) in inner.control_msg.iter().take(read_size).enumerate() {
data[i] = *x;
}
} else {
for (i, x) in inner.control_msg.drain(..read_size).enumerate() {
data[i] = x;
}
self.base.signal_clear(Signal::SOCKET_CONTROL_READABLE);
if let Some(peer) = self.peer.upgrade() {
peer.base.signal_set(Signal::SOCKET_CONTROL_WRITABLE);
}
}
Ok(read_size)
}
fn read_data(&self, options: SocketFlags, data: &mut [u8]) -> ZxResult<usize> {
let data_len = self.inner.lock().data.len(); let data_len = self.inner.lock().data.len();
if data_len == 0 { if data_len == 0 {
let _peer = self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)?; let _peer = self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)?;
@ -364,6 +325,12 @@ impl Socket {
Ok(()) Ok(())
} }
/// Set the read threshold of the socket.
///
/// When the bytes queued on the socket (available for reading) is equal to
/// or greater than this value, the **SOCKET_READ_THRESHOLD** signal is asserted.
/// Read threshold signalling is disabled by default (and when set, writing
/// a value of 0 for this property disables it).
pub fn set_read_threshold(&self, threshold: usize) -> ZxResult { pub fn set_read_threshold(&self, threshold: usize) -> ZxResult {
if threshold > SOCKET_SIZE { if threshold > SOCKET_SIZE {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
@ -380,6 +347,12 @@ impl Socket {
Ok(()) Ok(())
} }
/// Set the write threshold of the socket.
///
/// When the space available for writing on the socket is equal to or
/// greater than this value, the **SOCKET_WRITE_THRESHOLD** signal is asserted.
/// Write threshold signalling is disabled by default (and when set, writing a
/// value of 0 for this property disables it).
pub fn set_write_threshold(&self, threshold: usize) -> ZxResult { pub fn set_write_threshold(&self, threshold: usize) -> ZxResult {
let peer = self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)?; let peer = self.peer.upgrade().ok_or(ZxError::PEER_CLOSED)?;
if threshold > SOCKET_SIZE { if threshold > SOCKET_SIZE {
@ -396,6 +369,7 @@ impl Socket {
Ok(()) Ok(())
} }
/// Get the read and write thresholds of the socket.
pub fn get_rx_tx_threshold(&self) -> (usize, usize) { pub fn get_rx_tx_threshold(&self) -> (usize, usize) {
let inner = self.inner.lock(); let inner = self.inner.lock();
(inner.read_threshold, inner.write_threshold) (inner.read_threshold, inner.write_threshold)
@ -410,6 +384,7 @@ impl Drop for Socket {
} }
} }
/// The information of a socket
#[repr(C)] #[repr(C)]
#[derive(Default)] #[derive(Default)]
pub struct SocketInfo { pub struct SocketInfo {

View File

@ -32,14 +32,13 @@ impl Syscall<'_> {
if count > 0 && user_bytes.is_null() { if count > 0 && user_bytes.is_null() {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
} }
let options = SocketFlags::from_bits(options).ok_or(ZxError::INVALID_ARGS)?; if options != 0 {
if !(options - SocketFlags::SOCKET_CONTROL).is_empty() {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
} }
let proc = self.thread.proc(); let proc = self.thread.proc();
let socket = proc.get_object_with_rights::<Socket>(handle_value, Rights::WRITE)?; let socket = proc.get_object_with_rights::<Socket>(handle_value, Rights::WRITE)?;
let data = user_bytes.read_array(count)?; let data = user_bytes.read_array(count)?;
let actual_count = socket.write(options, &data)?; let actual_count = socket.write(&data)?;
actual_count_ptr.write_if_not_null(actual_count)?; actual_count_ptr.write_if_not_null(actual_count)?;
Ok(()) Ok(())
} }
@ -60,7 +59,7 @@ impl Syscall<'_> {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
} }
let options = SocketFlags::from_bits(options).ok_or(ZxError::INVALID_ARGS)?; let options = SocketFlags::from_bits(options).ok_or(ZxError::INVALID_ARGS)?;
if !(options - SocketFlags::SOCKET_CONTROL - SocketFlags::SOCKET_PEEK).is_empty() { if !(options - SocketFlags::SOCKET_PEEK).is_empty() {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
} }
let proc = self.thread.proc(); let proc = self.thread.proc();