WIP: New event system

This commit is contained in:
Jeremy Soller
2018-05-20 11:08:37 -06:00
parent 63351f4ca6
commit 99a3bff2da
15 changed files with 248 additions and 245 deletions

View File

@@ -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![(

View File

@@ -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
});
}
}
}
}

View File

@@ -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))?;

View File

@@ -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;

View 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
View 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
});
}
}
}
}
}

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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))
}
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();
}
}

View File

@@ -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 {

View File

@@ -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> {

View File

@@ -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();
}
}