forked from rcore-os/zCore
add docs and delete deprecated options and methods (about control) in `socket`
This commit is contained in:
parent
745a53b903
commit
590131ee7b
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue