From 82ff7859321d830b8c274cdbb7bc5e85f81b1fcb Mon Sep 17 00:00:00 2001 From: pjht Date: Fri, 20 Sep 2024 14:41:35 -0500 Subject: [PATCH] Add poll support --- Cargo.lock | 8 +++- Cargo.toml | 1 + src/lib.rs | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55e35ec..b4389da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,12 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "byteorder" @@ -77,6 +80,7 @@ checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" name = "file_rpc" version = "0.1.0" dependencies = [ + "bitflags", "parking_lot", "postcard", "serde", diff --git a/Cargo.toml b/Cargo.toml index 2a2f2a3..59711c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +bitflags = { version = "2.6.0", features = ["serde"] } parking_lot = "0.12.3" postcard = { version = "1.0.8", features = ["experimental-derive", "use-std"] } serde = { version = "1.0.144" } diff --git a/src/lib.rs b/src/lib.rs index 6dd3561..51351d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,32 @@ use std::{ borrow::Cow, boxed::Box, - os::mikros::ipc::rpc::{self, IncomingCall}, + os::mikros::ipc::{ + self, + rpc::{self, CallId, IncomingCall}, + }, vec::Vec, }; +use bitflags::bitflags; use parking_lot::RwLock; +use serde::{Deserialize, Serialize}; + +bitflags! { + #[derive(Serialize, Deserialize, Clone, Copy)] + pub struct PollEvents: u16 { + const POLLIN = 1<<0 | 1<<1; + const POLLRDNORM = 1<<0; + const POLLRDBAND = 1<<1; + const POLLPRI = 1<<2; + const POLLOUT = 1<<3; + const POLLWRNORM = 1<<3; + const POLLWRBAND = 1<<4; + const POLLERR = 1<<5; + const POLLHUP = 1<<6; + const POLLNVAL = 1<<7; + } +} static SERVER: RwLock>> = RwLock::new(None); @@ -17,11 +38,77 @@ pub trait Server: Send + Sync { fn close(&self, fd: u64); fn size(&self, fd: u64) -> Option; fn dup(&self, fd: u64) -> Option; + fn register_poll(&self, _fd: u64, _events: PollEvents) -> u64 { + 0 + } + fn poll(&self, _poll_id: u64) -> Option { + None + } + fn cancel_poll(&self, _poll_id: u64) {} } #[derive(Copy, Clone)] pub struct Client(u64); +#[derive(Copy, Clone)] +pub struct PendingPoll { + client: Client, + call_id: CallId, + poll_id: u64, +} + +impl PendingPoll { + fn cancel(&self) { + postcard::from_bytes( + &rpc::send_call( + self.client.0, + PROTO, + 7, + &postcard::to_stdvec(&self.poll_id).unwrap(), + ) + .get_return(), + ) + .unwrap() + } + + pub fn try_get_result(&self) -> Option { + let res: PollEvents = postcard::from_bytes(&*self.call_id.try_get_return()?).unwrap(); + Some(res) + } + + pub fn get_list_result(polls: &[Self]) -> Vec { + let mut result_vec = Vec::with_capacity(polls.len()); + loop { + let mut poll_returned = false; + let mut first_returned = 0; + for (i, poll) in polls.iter().enumerate() { + if let Some(poll_result) = poll.try_get_result() { + result_vec.push(poll_result); + if !poll_returned { + first_returned = i; + } + poll_returned = true; + } else if poll_returned { + poll.cancel(); + if let Some(poll_result) = poll.try_get_result() { + result_vec.push(poll_result); + } + } + } + if poll_returned { + for poll in &polls[0..first_returned] { + poll.cancel(); + if let Some(poll_result) = poll.try_get_result() { + result_vec.push(poll_result); + } + } + return result_vec; + } + ipc::process_messages(); + } + } +} + impl Client { pub fn new(pid: u64) -> Self { Self(pid) @@ -73,6 +160,25 @@ impl Client { ) .unwrap() } + + pub fn poll(self, fd: u64, events: PollEvents) -> PendingPoll { + let poll_id = postcard::from_bytes( + &rpc::send_call( + self.0, + PROTO, + 5, + &postcard::to_stdvec(&(fd, events)).unwrap(), + ) + .get_return(), + ) + .unwrap(); + let call_id = rpc::send_call(self.0, PROTO, 6, &postcard::to_stdvec(&poll_id).unwrap()); + PendingPoll { + client: self, + poll_id, + call_id, + } + } } pub fn register_server(server: Box) { @@ -117,6 +223,23 @@ fn callback(call: IncomingCall) { let ret = postcard::to_stdvec(&server.dup(fd)).unwrap(); call.send_return(&ret); } + 5 => { + let (fd, events) = postcard::from_bytes(call.args()).unwrap(); + let ret = postcard::to_stdvec(&server.register_poll(fd, events)).unwrap(); + call.send_return(&ret); + } + 6 => { + let poll_id = postcard::from_bytes(call.args()).unwrap(); + if let Some(ret) = server.poll(poll_id) { + let ret = postcard::to_stdvec(&ret).unwrap(); + call.send_return(&ret); + } + } + 7 => { + let poll_id = postcard::from_bytes(call.args()).unwrap(); + let ret = postcard::to_stdvec(&server.cancel_poll(poll_id)).unwrap(); + call.send_return(&ret); + } _ => (), } }