WIP: New event system
This commit is contained in:
@@ -10,9 +10,9 @@ use context::file::FileDescriptor;
|
||||
use context::memory::{Grant, Memory, SharedMemory, Tls};
|
||||
use device;
|
||||
use scheme::{SchemeNamespace, FileHandle};
|
||||
use syscall::data::{Event, SigAction};
|
||||
use syscall::data::SigAction;
|
||||
use syscall::flag::SIG_DFL;
|
||||
use sync::{WaitMap, WaitQueue};
|
||||
use sync::WaitMap;
|
||||
|
||||
/// Unique identifier for a context (i.e. `pid`).
|
||||
use ::core::sync::atomic::AtomicUsize;
|
||||
@@ -150,8 +150,6 @@ pub struct Context {
|
||||
pub name: Arc<Mutex<Box<[u8]>>>,
|
||||
/// The current working directory
|
||||
pub cwd: Arc<Mutex<Vec<u8>>>,
|
||||
/// Kernel events
|
||||
pub events: Arc<WaitQueue<Event>>,
|
||||
/// The process environment
|
||||
pub env: Arc<Mutex<BTreeMap<Box<[u8]>, Arc<Mutex<Vec<u8>>>>>>,
|
||||
/// The open files in the scheme
|
||||
@@ -193,7 +191,6 @@ impl Context {
|
||||
grants: Arc::new(Mutex::new(Vec::new())),
|
||||
name: Arc::new(Mutex::new(Vec::new().into_boxed_slice())),
|
||||
cwd: Arc::new(Mutex::new(Vec::new())),
|
||||
events: Arc::new(WaitQueue::new()),
|
||||
env: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
files: Arc::new(Mutex::new(Vec::new())),
|
||||
actions: Arc::new(Mutex::new(vec![(
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
use alloc::arc::{Arc, Weak};
|
||||
use alloc::BTreeMap;
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use context;
|
||||
use scheme::{FileHandle, SchemeId};
|
||||
use sync::WaitQueue;
|
||||
use syscall::data::Event;
|
||||
|
||||
type EventList = Weak<WaitQueue<Event>>;
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct RegKey {
|
||||
scheme_id: SchemeId,
|
||||
event_id: usize,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct ProcessKey {
|
||||
context_id: context::context::ContextId,
|
||||
fd: FileHandle,
|
||||
}
|
||||
|
||||
type Registry = BTreeMap<RegKey, BTreeMap<ProcessKey, 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: FileHandle, scheme_id: SchemeId, event_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(RegKey {
|
||||
scheme_id: scheme_id,
|
||||
event_id: event_id
|
||||
}).or_insert_with(|| {
|
||||
BTreeMap::new()
|
||||
});
|
||||
let process_key = ProcessKey {
|
||||
context_id: context_id,
|
||||
fd: fd
|
||||
};
|
||||
if entry.contains_key(&process_key) {
|
||||
false
|
||||
} else {
|
||||
entry.insert(process_key, events);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unregister(fd: FileHandle, scheme_id: SchemeId, event_id: usize) {
|
||||
let mut registry = registry_mut();
|
||||
|
||||
let mut remove = false;
|
||||
let key = RegKey {
|
||||
scheme_id: scheme_id,
|
||||
event_id: event_id
|
||||
};
|
||||
if let Some(entry) = registry.get_mut(&key) {
|
||||
let process_key = ProcessKey {
|
||||
context_id: context::context_id(),
|
||||
fd: fd,
|
||||
};
|
||||
entry.remove(&process_key);
|
||||
|
||||
if entry.is_empty() {
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if remove {
|
||||
registry.remove(&key);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trigger(scheme_id: SchemeId, event_id: usize, flags: usize, data: usize) {
|
||||
let registry = registry();
|
||||
let key = RegKey {
|
||||
scheme_id: scheme_id,
|
||||
event_id: event_id
|
||||
};
|
||||
if let Some(event_lists) = registry.get(&key) {
|
||||
for entry in event_lists.iter() {
|
||||
if let Some(event_list) = entry.1.upgrade() {
|
||||
event_list.send(Event {
|
||||
id: (entry.0).fd.into(),
|
||||
flags: flags,
|
||||
data: data
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-8
@@ -1,11 +1,11 @@
|
||||
//! File structs
|
||||
|
||||
use alloc::arc::Arc;
|
||||
use event;
|
||||
use spin::RwLock;
|
||||
use scheme::{self, SchemeId};
|
||||
use syscall::error::{Result, Error, EBADF};
|
||||
use scheme::FileHandle;
|
||||
use context;
|
||||
|
||||
/// A file description
|
||||
#[derive(Debug)]
|
||||
@@ -23,20 +23,17 @@ pub struct FileDescription {
|
||||
pub struct FileDescriptor {
|
||||
/// Corresponding file description
|
||||
pub description: Arc<RwLock<FileDescription>>,
|
||||
/// If events are on, this is the event ID
|
||||
pub event: Option<usize>,
|
||||
/// Cloexec flag
|
||||
pub cloexec: bool,
|
||||
}
|
||||
|
||||
impl FileDescriptor {
|
||||
pub fn close(self, fd: FileHandle) -> Result<usize> {
|
||||
if let Some(event_id) = self.event {
|
||||
context::event::unregister(fd, self.description.read().scheme, event_id);
|
||||
}
|
||||
|
||||
pub fn close(self) -> Result<usize> {
|
||||
if let Ok(file) = Arc::try_unwrap(self.description) {
|
||||
let file = file.into_inner();
|
||||
|
||||
event::unregister_file(file.scheme, file.number);
|
||||
|
||||
let scheme = {
|
||||
let schemes = scheme::schemes();
|
||||
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -21,9 +21,6 @@ mod list;
|
||||
/// Context switch function
|
||||
mod switch;
|
||||
|
||||
/// Event handling
|
||||
pub mod event;
|
||||
|
||||
/// File struct - defines a scheme and a file number
|
||||
pub mod file;
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use alloc::vec_deque::VecDeque;
|
||||
use core::mem;
|
||||
use spin::{Once, Mutex, MutexGuard};
|
||||
|
||||
use context::event;
|
||||
use event;
|
||||
use scheme::SchemeId;
|
||||
use syscall::data::TimeSpec;
|
||||
use syscall::flag::{CLOCK_MONOTONIC, CLOCK_REALTIME, EVENT_READ};
|
||||
@@ -65,7 +64,7 @@ pub fn trigger() {
|
||||
|
||||
if trigger {
|
||||
let timeout = registry.remove(i).unwrap();
|
||||
event::trigger(timeout.scheme_id, timeout.event_id, EVENT_READ, mem::size_of::<TimeSpec>());
|
||||
event::trigger(timeout.scheme_id, timeout.event_id, EVENT_READ);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user