use core::future::Future; use crate::buffer::ByteBuffer; use alloc::sync::Arc; use alloc::vec::Vec; use mammoth::cap::Capability; use mammoth::syscall; use mammoth::task::Spawner; use mammoth::task::Task; use mammoth::thread; use mammoth::thread::JoinHandle; use mammoth::zion::z_cap_t; use mammoth::zion::ZError; pub trait YunqServer { fn server_loop(&mut self) { loop { let mut byte_buffer = ByteBuffer::<1024>::new(); let mut cap_buffer = vec![0; 10]; let (_, _, reply_port_cap) = syscall::endpoint_recv( self.endpoint_cap(), byte_buffer.mut_slice(), &mut cap_buffer, ) .expect("Failed to call endpoint recv"); let method = byte_buffer .at::(8) .expect("Failed to access request length."); let resp = self.handle_request(method, &mut byte_buffer, &mut cap_buffer); match resp { Ok(resp_len) => syscall::reply_port_send( reply_port_cap, byte_buffer.slice(resp_len), &cap_buffer, ) .expect("Failed to reply"), Err(err) => { crate::message::serialize_error(&mut byte_buffer, err); syscall::reply_port_send(reply_port_cap, byte_buffer.slice(0x10), &[]) .expect("Failed to reply w/ error") } } } } fn endpoint_cap(&self) -> &Capability; fn create_client_cap(&self) -> Result { self.endpoint_cap() .duplicate(!mammoth::zion::kZionPerm_Read) } fn handle_request( &mut self, method_number: u64, byte_buffer: &mut ByteBuffer<1024>, cap_buffer: &mut Vec, ) -> Result; } pub fn spawn_server_thread(mut server: T) -> JoinHandle where T: YunqServer + Send + 'static, { thread::spawn(move || server.server_loop()) } pub trait AsyncYunqServer where Self: Send + Sync + 'static, { fn server_loop(self: Arc, spawner: Spawner) { loop { let mut byte_buffer = ByteBuffer::<1024>::new(); let mut cap_buffer = vec![0; 10]; let (_, _, reply_port_cap) = syscall::endpoint_recv( self.endpoint_cap(), byte_buffer.mut_slice(), &mut cap_buffer, ) .expect("Failed to call endpoint recv"); let method = byte_buffer .at::(8) .expect("Failed to access request length."); let self_clone = self.clone(); spawner.spawn(Task::new(async move { self_clone .handle_request_and_response(method, byte_buffer, cap_buffer, reply_port_cap) .await })); } } fn handle_request_and_response( &self, method: u64, mut byte_buffer: ByteBuffer<1024>, mut cap_buffer: Vec, reply_port_cap: Capability, ) -> impl Future + Sync + Send { async move { let resp = self .handle_request(method, &mut byte_buffer, &mut cap_buffer) .await; match resp { Ok(resp_len) => syscall::reply_port_send( reply_port_cap, byte_buffer.slice(resp_len), &cap_buffer, ) .expect("Failed to reply"), Err(err) => { crate::message::serialize_error(&mut byte_buffer, err); syscall::reply_port_send(reply_port_cap, byte_buffer.slice(0x10), &[]) .expect("Failed to reply w/ error") } } } } fn endpoint_cap(&self) -> &Capability; fn create_client_cap(&self) -> Result { self.endpoint_cap() .duplicate(!mammoth::zion::kZionPerm_Read) } fn handle_request( &self, method_number: u64, byte_buffer: &mut ByteBuffer<1024>, cap_buffer: &mut Vec, ) -> impl Future> + Sync + Send; } pub fn spawn_async_server_thread(server: Arc, spawner: Spawner) -> JoinHandle where T: AsyncYunqServer + Send + Sync + 'static, { thread::spawn(move || { server.server_loop(spawner); }) }