feat(userspace): Call/ReplyRecv IPC, malformed-request replies, servers exit on dead endpoint; drop send/receive compat, select!, async_syscall
This commit is contained in:
@@ -2,9 +2,10 @@ use crate::syscall;
|
||||
use types::bounded::CapSlot;
|
||||
use types::display::{Color, Dimension, ScreenCoord};
|
||||
|
||||
/// A failed call reads as an error reply (tag `usize::MAX`).
|
||||
fn ipc(ep: CapSlot, w0: usize, w1: usize, w2: usize, w3: usize) -> (usize, usize, usize, usize) {
|
||||
syscall::send(ep, w0, w1, w2, w3);
|
||||
syscall::receive(ep)
|
||||
let r = syscall::request(ep, [w0, w1, w2, w3]).unwrap_or([usize::MAX, 0, 0, 0]);
|
||||
(r[0], r[1], r[2], r[3])
|
||||
}
|
||||
|
||||
pub fn draw_rect(
|
||||
|
||||
@@ -23,9 +23,10 @@ fn pack_path(path: &[u8]) -> (usize, usize) {
|
||||
(usize::from_le_bytes(w0), usize::from_le_bytes(w1))
|
||||
}
|
||||
|
||||
/// A failed call reads as an error reply (tag `usize::MAX`).
|
||||
fn ipc(ep: CapSlot, w0: usize, w1: usize, w2: usize, w3: usize) -> (usize, usize, usize, usize) {
|
||||
syscall::send(ep, w0, w1, w2, w3);
|
||||
syscall::receive(ep)
|
||||
let r = syscall::request(ep, [w0, w1, w2, w3]).unwrap_or([usize::MAX, 0, 0, 0]);
|
||||
(r[0], r[1], r[2], r[3])
|
||||
}
|
||||
|
||||
pub fn open(ep: CapSlot, path: &[u8]) -> Option<FileHandle> {
|
||||
|
||||
@@ -38,8 +38,7 @@ fn decode_key(kind: usize, extra: usize) -> Option<Key> {
|
||||
}
|
||||
|
||||
pub fn poll_event(ep: CapSlot) -> Option<InputEvent> {
|
||||
syscall::send(ep, 0, 0, 0, 0);
|
||||
let (tag, kind, extra, _) = syscall::receive(ep);
|
||||
let [tag, kind, extra, _] = syscall::request(ep, [0; 4]).ok()?;
|
||||
match tag {
|
||||
0 => None,
|
||||
1 => decode_key(kind, extra).map(InputEvent::KeyDown),
|
||||
|
||||
@@ -243,14 +243,6 @@ pub fn create_endpoint() -> Option<CapSlot> {
|
||||
slot_of(call0(SYS_CREATE_ENDPOINT)).ok()
|
||||
}
|
||||
|
||||
/// Sends four words; returns 0 on success (kept for existing callers).
|
||||
pub fn send(endpoint: CapSlot, w0: usize, w1: usize, w2: usize, w3: usize) -> usize {
|
||||
match send_msg(endpoint, [w0, w1, w2, w3], None) {
|
||||
Ok(()) => 0,
|
||||
Err(e) => e as usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_msg(endpoint: CapSlot, words: [usize; 4], cap: Option<CapSlot>) -> Result<()> {
|
||||
raw(
|
||||
SYS_SEND,
|
||||
@@ -259,12 +251,6 @@ pub fn send_msg(endpoint: CapSlot, words: [usize; 4], cap: Option<CapSlot>) -> R
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
/// Receives and returns just the words (kept for existing callers).
|
||||
pub fn receive(endpoint: CapSlot) -> (usize, usize, usize, usize) {
|
||||
let w = receive_msg(endpoint).map_or([0; 4], |r| r.words());
|
||||
(w[0], w[1], w[2], w[3])
|
||||
}
|
||||
|
||||
pub fn receive_msg(endpoint: CapSlot) -> Result<Received> {
|
||||
raw(SYS_RECEIVE, [endpoint.value() as usize, 0, 0, 0, 0, 0]).and_then(Received::decode)
|
||||
}
|
||||
@@ -278,6 +264,16 @@ pub fn call(endpoint: CapSlot, words: [usize; 4], cap: Option<CapSlot>) -> Resul
|
||||
.and_then(Received::decode)
|
||||
}
|
||||
|
||||
/// Calls a server with four words and returns its reply's words. Needs
|
||||
/// only Execute on the endpoint; the reply comes back through the
|
||||
/// kernel's reply slot, so it can never reach another client.
|
||||
pub fn request(endpoint: CapSlot, words: [usize; 4]) -> Result<[usize; 4]> {
|
||||
match call(endpoint, words, None)? {
|
||||
Received::Signal { .. } => Err(Error::InvalidArgument),
|
||||
reply => Ok(reply.words()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Answers the last `Call` this thread received.
|
||||
pub fn reply(words: [usize; 4], cap: Option<CapSlot>) -> Result<()> {
|
||||
raw(SYS_REPLY, message_regs(0, words, cap)).map(|_| ())
|
||||
|
||||
Reference in New Issue
Block a user