moana_std 0.1.2

moana 用户标准库
Documentation
//! connect 系列 syscall 用户态接口(client 端)

use moa_uapi::{
    connect::ConnHandle,
    error::{
        ERR_CHANNEL_CLOSED, ERR_CONNECTION_CLOSED, ERR_CONNECTION_REFUSED, ERR_FAULT, ERR_INVAL,
        ERR_NO_RESOURCE, ERR_NOT_FOUND, ERR_QUEUE_FULL, ERR_TIMEOUT,
    },
    space::SpaceId,
    sysnr::{SYSNR_CONNECT, SYSNR_DISCONNECT, SYSNR_SEND_PULSE, SYSNR_SENDV},
    types::{IoVec, Timeout},
};

/// connect 系列 syscall 返回类型
pub type Result<T> = core::result::Result<T, ConnectError>;

define_syscall_error! {
    /// connect 系列 syscall 错误
    pub enum ConnectError {
        /// 目标不存在
        NotFound = ERR_NOT_FOUND,
        /// 无效参数
        Inval = ERR_INVAL,
        /// 资源配额耗尽
        NoResource = ERR_NO_RESOURCE,
        /// 无效指针
        Fault = ERR_FAULT,
        /// 超时
        Timeout = ERR_TIMEOUT,
        /// 通道已关闭
        ChannelClosed = ERR_CHANNEL_CLOSED,
        /// 连接已关闭
        ConnectionClosed = ERR_CONNECTION_CLOSED,
        /// 连接被拒绝
        ConnectionRefused = ERR_CONNECTION_REFUSED,
        /// pulse 队列已满
        QueueFull = ERR_QUEUE_FULL,
    }
}

/// 连接到目标地址空间的指定通道
///
/// 鉴权由 server 在首条消息时通过 `connect_info` 完成。
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn connect(spaceid: SpaceId, channel_index: u32) -> Result<ConnHandle> {
    let ret =
        unsafe { super::arch::syscall2(SYSNR_CONNECT, spaceid.raw(), channel_index as usize) };
    if ret < 0 { Err(ConnectError::from_raw(ret)) } else { Ok(ConnHandle::from_raw(ret as u32)) }
}

/// 断开连接
pub fn disconnect(conn: ConnHandle) -> Result<()> {
    let ret = unsafe { super::arch::syscall1(SYSNR_DISCONNECT, conn.raw() as usize) };
    if ret < 0 { Err(ConnectError::from_raw(ret)) } else { Ok(()) }
}

/// 发送消息并阻塞等待回复(同步 RPC)
///
/// 返回 server 回复的 status(0 = 成功,非零 = 应用错误码)。
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
pub fn sendv(
    conn: ConnHandle,
    send_iov: &[IoVec],
    recv_iov: &mut [IoVec],
    timeout: Timeout,
) -> Result<u32> {
    let ret = unsafe {
        super::arch::syscall6(
            SYSNR_SENDV,
            conn.raw() as usize,
            send_iov.as_ptr() as usize,
            send_iov.len(),
            recv_iov.as_mut_ptr() as usize,
            recv_iov.len(),
            timeout.raw() as usize,
        )
    };
    if ret < 0 { Err(ConnectError::from_raw(ret)) } else { Ok(ret as u32) }
}

/// 发送异步 pulse(非阻塞)
///
/// `code` 有效范围 `0..=isize::MAX`(负值系统保留)。
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn send_pulse(conn: ConnHandle, code: isize, value: usize) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall3(SYSNR_SEND_PULSE, conn.raw() as usize, code as usize, value)
    };
    if ret < 0 { Err(ConnectError::from_raw(ret)) } else { Ok(()) }
}