Files
RedBear-OS/src/scheme/event.rs
T
2024-07-15 17:50:18 +02:00

77 lines
2.0 KiB
Rust

use alloc::sync::Arc;
use core::mem;
use syscall::O_NONBLOCK;
use crate::{
context::file::InternalFlags,
event::{next_queue_id, queues, queues_mut, EventQueue, EventQueueId},
syscall::{
data::Event,
error::*,
usercopy::{UserSliceRo, UserSliceWo},
},
};
use super::{CallerCtx, KernelScheme, OpenResult};
pub struct EventScheme;
impl KernelScheme for EventScheme {
fn kopen(&self, _path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
let id = next_queue_id();
queues_mut().insert(id, Arc::new(EventQueue::new(id)));
Ok(OpenResult::SchemeLocal(id.get(), InternalFlags::empty()))
}
fn close(&self, id: usize) -> Result<()> {
let id = EventQueueId::from(id);
queues_mut()
.remove(&id)
.ok_or(Error::new(EBADF))
.and(Ok(()))
}
fn kread(&self, id: usize, buf: UserSliceWo, flags: u32, _stored_flags: u32) -> Result<usize> {
let id = EventQueueId::from(id);
let queue = {
let handles = queues();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
handle.clone()
};
queue.read(buf, flags & O_NONBLOCK as u32 == 0)
}
fn kwrite(
&self,
id: usize,
buf: UserSliceRo,
_flags: u32,
_stored_flags: u32,
) -> Result<usize> {
let id = EventQueueId::from(id);
let queue = {
let handles = queues();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
handle.clone()
};
let mut events_written = 0;
for chunk in buf.in_exact_chunks(mem::size_of::<Event>()) {
let event = unsafe { chunk.read_exact::<Event>()? };
if queue.write(&[event])? == 0 {
break;
}
events_written += 1;
}
Ok(events_written * mem::size_of::<Event>())
}
fn kfpath(&self, _id: usize, buf: UserSliceWo) -> Result<usize> {
buf.copy_common_bytes_from_slice(b"event:")
}
}