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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
167
src/event.rs
Normal file
167
src/event.rs
Normal file
@@ -0,0 +1,167 @@
|
||||
use alloc::arc::Arc;
|
||||
use alloc::BTreeMap;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use context;
|
||||
use scheme::SchemeId;
|
||||
use sync::WaitQueue;
|
||||
use syscall::data::Event;
|
||||
use syscall::error::{Error, Result, EBADF, ESRCH};
|
||||
|
||||
int_like!(EventQueueId, AtomicEventQueueId, usize, AtomicUsize);
|
||||
|
||||
pub struct EventQueue {
|
||||
id: EventQueueId,
|
||||
queue: WaitQueue<Event>,
|
||||
}
|
||||
|
||||
impl EventQueue {
|
||||
pub fn new(id: EventQueueId) -> EventQueue {
|
||||
EventQueue {
|
||||
id: id,
|
||||
queue: WaitQueue::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dup(&self, other: &EventQueue) {
|
||||
panic!("EventQeuue::dup");
|
||||
}
|
||||
|
||||
pub fn read(&self, events: &mut [Event]) -> Result<usize> {
|
||||
Ok(self.queue.receive_into(events, true))
|
||||
}
|
||||
|
||||
pub fn write(&self, events: &[Event]) -> Result<usize> {
|
||||
for event in events {
|
||||
let file = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
let mut files = context.files.lock();
|
||||
match files.get(event.id).ok_or(Error::new(EBADF))? {
|
||||
Some(file) => file.clone(),
|
||||
None => return Err(Error::new(EBADF))
|
||||
}
|
||||
};
|
||||
|
||||
let (scheme, number) = {
|
||||
let description = file.description.read();
|
||||
(description.scheme, description.number)
|
||||
};
|
||||
|
||||
register(
|
||||
RegKey { scheme, number },
|
||||
QueueKey { queue: self.id, id: event.id, data: event.data },
|
||||
event.flags
|
||||
);
|
||||
}
|
||||
|
||||
Ok(events.len())
|
||||
}
|
||||
}
|
||||
|
||||
pub type EventQueueList = BTreeMap<EventQueueId, Arc<EventQueue>>;
|
||||
|
||||
// Next queue id
|
||||
static NEXT_QUEUE_ID: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
|
||||
/// Get next queue id
|
||||
pub fn next_queue_id() -> EventQueueId {
|
||||
EventQueueId::from(NEXT_QUEUE_ID.fetch_add(1, Ordering::SeqCst))
|
||||
}
|
||||
|
||||
// Current event queues
|
||||
static QUEUES: Once<RwLock<EventQueueList>> = Once::new();
|
||||
|
||||
/// Initialize queues, called if needed
|
||||
fn init_queues() -> RwLock<EventQueueList> {
|
||||
RwLock::new(BTreeMap::new())
|
||||
}
|
||||
|
||||
/// Get the event queues list, const
|
||||
pub fn queues() -> RwLockReadGuard<'static, EventQueueList> {
|
||||
QUEUES.call_once(init_queues).read()
|
||||
}
|
||||
|
||||
/// Get the event queues list, mutable
|
||||
pub fn queues_mut() -> RwLockWriteGuard<'static, EventQueueList> {
|
||||
QUEUES.call_once(init_queues).write()
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct RegKey {
|
||||
pub scheme: SchemeId,
|
||||
pub number: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct QueueKey {
|
||||
pub queue: EventQueueId,
|
||||
pub id: usize,
|
||||
pub data: usize
|
||||
}
|
||||
|
||||
type Registry = BTreeMap<RegKey, BTreeMap<QueueKey, usize>>;
|
||||
|
||||
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(reg_key: RegKey, queue_key: QueueKey, flags: usize) {
|
||||
let mut registry = registry_mut();
|
||||
|
||||
let entry = registry.entry(reg_key).or_insert_with(|| {
|
||||
BTreeMap::new()
|
||||
});
|
||||
|
||||
if flags == 0 {
|
||||
entry.remove(&queue_key);
|
||||
} else {
|
||||
entry.insert(queue_key, flags);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unregister_file(scheme: SchemeId, number: usize) {
|
||||
let mut registry = registry_mut();
|
||||
|
||||
registry.remove(&RegKey { scheme, number });
|
||||
}
|
||||
|
||||
//TODO: Implement unregister_queue
|
||||
// pub fn unregister_queue(scheme: SchemeId, number: usize) {
|
||||
//
|
||||
// }
|
||||
|
||||
pub fn trigger(scheme: SchemeId, number: usize, flags: usize) {
|
||||
let registry = registry();
|
||||
|
||||
if let Some(queue_list) = registry.get(&RegKey { scheme, number }) {
|
||||
for (queue_key, queue_flags) in queue_list.iter() {
|
||||
let common_flags = flags & queue_flags;
|
||||
if common_flags != 0 {
|
||||
let queues = queues();
|
||||
if let Some(queue) = queues.get(&queue_key.queue) {
|
||||
queue.queue.send(Event {
|
||||
id: queue_key.id,
|
||||
flags: common_flags,
|
||||
data: queue_key.data
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
#![feature(asm)]
|
||||
#![feature(collections)]
|
||||
#![feature(concat_idents)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(const_atomic_usize_new)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_max_value)]
|
||||
@@ -83,6 +82,9 @@ pub mod devices;
|
||||
#[cfg(not(feature="doc"))]
|
||||
pub mod elf;
|
||||
|
||||
/// Event handling
|
||||
pub mod event;
|
||||
|
||||
/// External functions
|
||||
pub mod externs;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use core::sync::atomic::Ordering;
|
||||
use spin::Once;
|
||||
|
||||
use context;
|
||||
use device::serial::COM1;
|
||||
use event;
|
||||
use scheme::*;
|
||||
use sync::WaitQueue;
|
||||
use syscall::flag::{EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK};
|
||||
@@ -20,8 +20,8 @@ fn init_input() -> WaitQueue<u8> {
|
||||
|
||||
/// Add to the input queue
|
||||
pub fn debug_input(b: u8) {
|
||||
let len = INPUT.call_once(init_input).send(b);
|
||||
context::event::trigger(DEBUG_SCHEME_ID.load(Ordering::SeqCst), 0, EVENT_READ, len);
|
||||
INPUT.call_once(init_input).send(b);
|
||||
event::trigger(DEBUG_SCHEME_ID.load(Ordering::SeqCst), 0, EVENT_READ);
|
||||
}
|
||||
|
||||
pub struct DebugScheme {
|
||||
|
||||
@@ -1,75 +1,73 @@
|
||||
use alloc::arc::{Arc, Weak};
|
||||
use alloc::BTreeMap;
|
||||
use alloc::arc::Arc;
|
||||
use core::{mem, slice};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use spin::RwLock;
|
||||
|
||||
use context;
|
||||
use sync::WaitQueue;
|
||||
use event::{EventQueue, EventQueueId, next_queue_id, queues, queues_mut};
|
||||
use syscall::data::Event;
|
||||
use syscall::error::*;
|
||||
use syscall::scheme::Scheme;
|
||||
|
||||
pub struct EventScheme {
|
||||
next_id: AtomicUsize,
|
||||
handles: RwLock<BTreeMap<usize, Weak<WaitQueue<Event>>>>
|
||||
}
|
||||
|
||||
impl EventScheme {
|
||||
pub fn new() -> EventScheme {
|
||||
EventScheme {
|
||||
next_id: AtomicUsize::new(0),
|
||||
handles: RwLock::new(BTreeMap::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct EventScheme;
|
||||
|
||||
impl Scheme for EventScheme {
|
||||
fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
let handle = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
context.events.clone()
|
||||
};
|
||||
let id = next_queue_id();
|
||||
queues_mut().insert(id, Arc::new(EventQueue::new(id)));
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
self.handles.write().insert(id, Arc::downgrade(&handle));
|
||||
|
||||
Ok(id)
|
||||
Ok(id.into())
|
||||
}
|
||||
|
||||
fn dup(&self, id: usize, buf: &[u8]) -> Result<usize> {
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
if ! buf.is_empty() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
let handle_weak = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
handle_weak.upgrade().ok_or(Error::new(EBADF))?
|
||||
let old_queue = {
|
||||
let handles = queues();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
handle.clone()
|
||||
};
|
||||
|
||||
let new_id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
self.handles.write().insert(new_id, Arc::downgrade(&handle));
|
||||
Ok(new_id)
|
||||
let new_id = next_queue_id();
|
||||
let new_queue = Arc::new(EventQueue::new(new_id));
|
||||
queues_mut().insert(new_id, new_queue.clone());
|
||||
new_queue.dup(&old_queue);
|
||||
|
||||
Ok(new_id.into())
|
||||
}
|
||||
|
||||
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
let handle_weak = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
handle_weak.upgrade().ok_or(Error::new(EBADF))?
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
let queue = {
|
||||
let handles = queues();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
handle.clone()
|
||||
};
|
||||
|
||||
let event_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Event, buf.len()/mem::size_of::<Event>()) };
|
||||
Ok(handle.receive_into(event_buf, true) * mem::size_of::<Event>())
|
||||
Ok(queue.read(event_buf)? * mem::size_of::<Event>())
|
||||
}
|
||||
|
||||
fn write(&self, id: usize, buf: &[u8]) -> 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 event_buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Event, buf.len()/mem::size_of::<Event>()) };
|
||||
Ok(queue.write(event_buf)? * mem::size_of::<Event>())
|
||||
}
|
||||
|
||||
fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
let handle_weak = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
handle_weak.upgrade().ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
let handles = queues();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
|
||||
fn fpath(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
@@ -83,12 +81,14 @@ impl Scheme for EventScheme {
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
let handle_weak = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
handle_weak.upgrade().ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
let handles = queues();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
let id = EventQueueId::from(id);
|
||||
queues_mut().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ use core::{mem, str};
|
||||
use core::sync::atomic::Ordering;
|
||||
use spin::Mutex;
|
||||
|
||||
use event;
|
||||
use interrupt::irq::acknowledge;
|
||||
use context;
|
||||
use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId};
|
||||
use syscall::error::*;
|
||||
use syscall::flag::EVENT_READ;
|
||||
@@ -19,7 +19,7 @@ static COUNTS: Mutex<[usize; 16]> = Mutex::new([0; 16]);
|
||||
#[no_mangle]
|
||||
pub extern fn irq_trigger(irq: u8) {
|
||||
COUNTS.lock()[irq as usize] += 1;
|
||||
context::event::trigger(IRQ_SCHEME_ID.load(Ordering::SeqCst), irq as usize, EVENT_READ, mem::size_of::<usize>());
|
||||
event::trigger(IRQ_SCHEME_ID.load(Ordering::SeqCst), irq as usize, EVENT_READ);
|
||||
}
|
||||
|
||||
pub struct IrqScheme;
|
||||
|
||||
@@ -118,7 +118,7 @@ impl SchemeList {
|
||||
self.names.insert(ns, BTreeMap::new());
|
||||
|
||||
self.insert(ns, Box::new(*b""), |scheme_id| Arc::new(Box::new(RootScheme::new(ns, scheme_id)))).unwrap();
|
||||
self.insert(ns, Box::new(*b"event"), |_| Arc::new(Box::new(EventScheme::new()))).unwrap();
|
||||
self.insert(ns, Box::new(*b"event"), |_| Arc::new(Box::new(EventScheme))).unwrap();
|
||||
self.insert(ns, Box::new(*b"env"), |_| Arc::new(Box::new(EnvScheme::new()))).unwrap();
|
||||
self.insert(ns, Box::new(*b"memory"), |_| Arc::new(Box::new(MemoryScheme))).unwrap();
|
||||
self.insert(ns, Box::new(*b"sys"), |_| Arc::new(Box::new(SysScheme::new()))).unwrap();
|
||||
|
||||
@@ -3,7 +3,7 @@ use alloc::{BTreeMap, VecDeque};
|
||||
use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||
use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use context;
|
||||
use event;
|
||||
use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId};
|
||||
use sync::WaitCondition;
|
||||
use syscall::error::{Error, Result, EAGAIN, EBADF, EINTR, EINVAL, EPIPE, ESPIPE};
|
||||
@@ -288,17 +288,15 @@ impl PipeWrite {
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
if let Some(ref vec_weak) = self.vec {
|
||||
if let Some(vec_lock) = vec_weak.upgrade() {
|
||||
let len = {
|
||||
{
|
||||
let mut vec = vec_lock.lock();
|
||||
|
||||
for &b in buf.iter() {
|
||||
vec.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
vec.len()
|
||||
};
|
||||
|
||||
context::event::trigger(self.scheme_id, self.event_id, EVENT_READ, len);
|
||||
event::trigger(self.scheme_id, self.event_id, EVENT_READ);
|
||||
self.condition.notify();
|
||||
|
||||
Ok(buf.len())
|
||||
@@ -314,7 +312,7 @@ impl PipeWrite {
|
||||
impl Drop for PipeWrite {
|
||||
fn drop(&mut self) {
|
||||
drop(self.vec.take());
|
||||
context::event::trigger(self.scheme_id, self.event_id, EVENT_READ, 0);
|
||||
event::trigger(self.scheme_id, self.event_id, EVENT_READ);
|
||||
self.condition.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@ use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use core::{mem, slice, usize};
|
||||
use spin::{Mutex, RwLock};
|
||||
|
||||
use context::{self, Context};
|
||||
use context::memory::Grant;
|
||||
use event;
|
||||
use paging::{InactivePageTable, Page, VirtualAddress};
|
||||
use paging::entry::EntryFlags;
|
||||
use paging::temporary_page::TemporaryPage;
|
||||
use context::{self, Context};
|
||||
use context::memory::Grant;
|
||||
use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId};
|
||||
use sync::{WaitQueue, WaitMap};
|
||||
use syscall::data::{Packet, Stat, StatVfs, TimeSpec};
|
||||
@@ -70,8 +71,8 @@ impl UserInner {
|
||||
fn call_inner(&self, packet: Packet) -> Result<usize> {
|
||||
let id = packet.id;
|
||||
|
||||
let len = self.todo.send(packet);
|
||||
context::event::trigger(self.root_id, self.handle_id, EVENT_READ, mem::size_of::<Packet>() * len);
|
||||
self.todo.send(packet);
|
||||
event::trigger(self.root_id, self.handle_id, EVENT_READ);
|
||||
|
||||
Error::demux(self.done.receive(&id))
|
||||
}
|
||||
@@ -178,7 +179,7 @@ impl UserInner {
|
||||
let mut packet = unsafe { *(buf.as_ptr() as *const Packet).offset(i as isize) };
|
||||
if packet.id == 0 {
|
||||
match packet.a {
|
||||
SYS_FEVENT => context::event::trigger(self.scheme_id.load(Ordering::SeqCst), packet.b, packet.c, packet.d),
|
||||
SYS_FEVENT => event::trigger(self.scheme_id.load(Ordering::SeqCst), packet.b, packet.c),
|
||||
_ => println!("Unknown scheme -> kernel message {}", packet.a)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -118,7 +118,6 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
|
||||
number: file_id,
|
||||
flags: flags & !O_CLOEXEC,
|
||||
})),
|
||||
event: None,
|
||||
cloexec: flags & O_CLOEXEC == O_CLOEXEC,
|
||||
}).ok_or(Error::new(EMFILE))
|
||||
}
|
||||
@@ -138,7 +137,6 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
|
||||
number: read_id,
|
||||
flags: O_RDONLY | flags & !O_ACCMODE & !O_CLOEXEC,
|
||||
})),
|
||||
event: None,
|
||||
cloexec: flags & O_CLOEXEC == O_CLOEXEC,
|
||||
}).ok_or(Error::new(EMFILE))?;
|
||||
|
||||
@@ -148,7 +146,6 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
|
||||
number: write_id,
|
||||
flags: O_WRONLY | flags & !O_ACCMODE & !O_CLOEXEC,
|
||||
})),
|
||||
event: None,
|
||||
cloexec: flags & O_CLOEXEC == O_CLOEXEC,
|
||||
}).ok_or(Error::new(EMFILE))?;
|
||||
|
||||
@@ -236,7 +233,7 @@ pub fn close(fd: FileHandle) -> Result<usize> {
|
||||
context.remove_file(fd).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
file.close(fd)
|
||||
file.close()
|
||||
}
|
||||
|
||||
fn duplicate_file(fd: FileHandle, buf: &[u8]) -> Result<FileDescriptor> {
|
||||
@@ -250,7 +247,6 @@ fn duplicate_file(fd: FileHandle, buf: &[u8]) -> Result<FileDescriptor> {
|
||||
if buf.is_empty() {
|
||||
Ok(FileDescriptor {
|
||||
description: Arc::clone(&file.description),
|
||||
event: None,
|
||||
cloexec: false,
|
||||
})
|
||||
} else {
|
||||
@@ -271,7 +267,6 @@ fn duplicate_file(fd: FileHandle, buf: &[u8]) -> Result<FileDescriptor> {
|
||||
number: new_id,
|
||||
flags: description.flags,
|
||||
})),
|
||||
event: None,
|
||||
cloexec: false,
|
||||
})
|
||||
}
|
||||
@@ -378,44 +373,7 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize) -> Result<usize> {
|
||||
|
||||
/// Register events for file
|
||||
pub fn fevent(fd: FileHandle, flags: usize) -> Result<usize> {
|
||||
let file = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
let mut files = context.files.lock();
|
||||
match *files.get_mut(fd.into()).ok_or(Error::new(EBADF))? {
|
||||
Some(ref mut file) => {
|
||||
let description = file.description.read();
|
||||
if let Some(event_id) = file.event.take() {
|
||||
println!("{:?}: {:?}:{}: events already registered: {}", fd, description.scheme, description.number, event_id);
|
||||
context::event::unregister(fd, description.scheme, event_id);
|
||||
}
|
||||
file.clone()
|
||||
},
|
||||
None => return Err(Error::new(EBADF))
|
||||
}
|
||||
};
|
||||
|
||||
let description = file.description.read();
|
||||
|
||||
let scheme = {
|
||||
let schemes = scheme::schemes();
|
||||
let scheme = schemes.get(description.scheme).ok_or(Error::new(EBADF))?;
|
||||
Arc::clone(&scheme)
|
||||
};
|
||||
let event_id = scheme.fevent(description.number, flags)?;
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
let mut files = context.files.lock();
|
||||
match *files.get_mut(fd.into()).ok_or(Error::new(EBADF))? {
|
||||
Some(ref mut file) => file.event = Some(event_id),
|
||||
None => return Err(Error::new(EBADF)),
|
||||
}
|
||||
}
|
||||
context::event::register(fd, description.scheme, event_id);
|
||||
Ok(0)
|
||||
Err(Error::new(ENOSYS))
|
||||
}
|
||||
|
||||
pub fn frename(fd: FileHandle, path: &[u8]) -> Result<usize> {
|
||||
|
||||
@@ -296,7 +296,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
|
||||
let new_file_option = if let Some(ref file) = *file_option {
|
||||
Some(FileDescriptor {
|
||||
description: Arc::clone(&file.description),
|
||||
event: None,
|
||||
cloexec: file.cloexec,
|
||||
})
|
||||
} else {
|
||||
@@ -755,7 +754,7 @@ fn exec_noreturn(
|
||||
}
|
||||
|
||||
if cloexec {
|
||||
let _ = file_option.take().unwrap().close(FileHandle::from(fd));
|
||||
let _ = file_option.take().unwrap().close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -933,7 +932,7 @@ pub fn exit(status: usize) -> ! {
|
||||
// Files must be closed while context is valid so that messages can be passed
|
||||
for (fd, file_option) in close_files.drain(..).enumerate() {
|
||||
if let Some(file) = file_option {
|
||||
let _ = file.close(FileHandle::from(fd));
|
||||
let _ = file.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user