Event support - demonstration in example scheme
This commit is contained in:
parent
616dfbc055
commit
0e8487cf83
12 changed files with 239 additions and 31 deletions
|
@ -1,9 +1,10 @@
|
|||
use alloc::arc::Arc;
|
||||
use alloc::boxed::Box;
|
||||
use collections::{BTreeMap, Vec};
|
||||
use collections::{BTreeMap, Vec, VecDeque};
|
||||
use spin::Mutex;
|
||||
|
||||
use arch;
|
||||
use syscall::data::Event;
|
||||
use super::file::File;
|
||||
use super::memory::{Grant, Memory, SharedMemory};
|
||||
|
||||
|
@ -39,6 +40,8 @@ pub struct Context {
|
|||
pub grants: Arc<Mutex<Vec<Grant>>>,
|
||||
/// The current working directory
|
||||
pub cwd: Arc<Mutex<Vec<u8>>>,
|
||||
/// Kernel events
|
||||
pub events: Arc<Mutex<VecDeque<Event>>>,
|
||||
/// The process environment
|
||||
pub env: Arc<Mutex<BTreeMap<Box<[u8]>, Arc<Mutex<Vec<u8>>>>>>,
|
||||
/// The open files in the scheme
|
||||
|
@ -60,6 +63,7 @@ impl Context {
|
|||
stack: None,
|
||||
grants: Arc::new(Mutex::new(Vec::new())),
|
||||
cwd: Arc::new(Mutex::new(Vec::new())),
|
||||
events: Arc::new(Mutex::new(VecDeque::new())),
|
||||
env: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
files: Arc::new(Mutex::new(Vec::new()))
|
||||
}
|
||||
|
|
80
kernel/context/event.rs
Normal file
80
kernel/context/event.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
use alloc::arc::{Arc, Weak};
|
||||
use collections::{BTreeMap, VecDeque};
|
||||
use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use context;
|
||||
use syscall::data::Event;
|
||||
|
||||
type EventList = Weak<Mutex<VecDeque<Event>>>;
|
||||
|
||||
type Registry = BTreeMap<(usize, usize), BTreeMap<(usize, usize), EventList>>;
|
||||
|
||||
static REGISTRY: Once<RwLock<Registry>> = Once::new();
|
||||
|
||||
/// Initialize registry, called if needed
|
||||
fn init_registry() -> RwLock<Registry> {
|
||||
RwLock::new(Registry::new())
|
||||
}
|
||||
|
||||
/// Get the global schemes list, const
|
||||
fn registry() -> RwLockReadGuard<'static, Registry> {
|
||||
REGISTRY.call_once(init_registry).read()
|
||||
}
|
||||
|
||||
/// Get the global schemes list, mutable
|
||||
pub fn registry_mut() -> RwLockWriteGuard<'static, Registry> {
|
||||
REGISTRY.call_once(init_registry).write()
|
||||
}
|
||||
|
||||
pub fn register(fd: usize, scheme_id: usize, id: usize) -> bool {
|
||||
let (context_id, events) = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().expect("event::register: No context");
|
||||
let context = context_lock.read();
|
||||
(context.id, Arc::downgrade(&context.events))
|
||||
};
|
||||
|
||||
let mut registry = registry_mut();
|
||||
let entry = registry.entry((scheme_id, id)).or_insert_with(|| {
|
||||
BTreeMap::new()
|
||||
});
|
||||
if entry.contains_key(&(context_id, fd)) {
|
||||
false
|
||||
} else {
|
||||
entry.insert((context_id, fd), events);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unregister(fd: usize, scheme_id: usize, id: usize) {
|
||||
let mut registry = registry_mut();
|
||||
|
||||
let mut remove = false;
|
||||
if let Some(entry) = registry.get_mut(&(scheme_id, id)) {
|
||||
entry.remove(&(context::context_id(), fd));
|
||||
|
||||
if entry.is_empty() {
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if remove {
|
||||
registry.remove(&(scheme_id, id));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trigger(scheme_id: usize, id: usize, flags: usize, data: usize) {
|
||||
let registry = registry();
|
||||
if let Some(event_lists) = registry.get(&(scheme_id, id)) {
|
||||
for entry in event_lists.iter() {
|
||||
if let Some(event_list_lock) = entry.1.upgrade() {
|
||||
let mut event_list = event_list_lock.lock();
|
||||
event_list.push_back(Event {
|
||||
id: (entry.0).1,
|
||||
flags: flags,
|
||||
data: data
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@ mod list;
|
|||
/// Context switch function
|
||||
mod switch;
|
||||
|
||||
/// Event handling
|
||||
pub mod event;
|
||||
|
||||
/// File struct - defines a scheme and a file number
|
||||
pub mod file;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue