Add nonblocking root scheme

This commit is contained in:
Jeremy Soller 2016-10-20 12:31:39 -06:00
parent dd1c0ca01d
commit 8fd25ee318
5 changed files with 20 additions and 31 deletions

View file

@ -41,7 +41,7 @@ impl Scheme for DebugScheme {
/// ///
/// Returns the number of bytes read /// Returns the number of bytes read
fn read(&self, _file: usize, buf: &mut [u8]) -> Result<usize> { fn read(&self, _file: usize, buf: &mut [u8]) -> Result<usize> {
Ok(INPUT.call_once(init_input).receive_into(buf)) Ok(INPUT.call_once(init_input).receive_into(buf, true))
} }
/// Write the `buffer` to the `file` /// Write the `buffer` to the `file`

View file

@ -59,7 +59,7 @@ impl Scheme for EventScheme {
}; };
let event_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Event, buf.len()/mem::size_of::<Event>()) }; 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) * mem::size_of::<Event>()) Ok(handle.receive_into(event_buf, true) * mem::size_of::<Event>())
} }
fn fsync(&self, id: usize) -> Result<usize> { fn fsync(&self, id: usize) -> Result<usize> {

View file

@ -27,7 +27,7 @@ impl RootScheme {
} }
impl Scheme for RootScheme { impl Scheme for RootScheme {
fn open(&self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> { fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid == 0 { if uid == 0 {
let context = { let context = {
let contexts = context::contexts(); let contexts = context::contexts();
@ -42,7 +42,7 @@ impl Scheme for RootScheme {
if schemes.get_name(path).is_some() { if schemes.get_name(path).is_some() {
return Err(Error::new(EEXIST)); return Err(Error::new(EEXIST));
} }
let inner = Arc::new(UserInner::new(id, context)); let inner = Arc::new(UserInner::new(id, flags, context));
let scheme_id = schemes.insert(path.to_vec().into_boxed_slice(), Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner))))).expect("failed to insert user scheme"); let scheme_id = schemes.insert(path.to_vec().into_boxed_slice(), Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner))))).expect("failed to insert user scheme");
inner.scheme_id.store(scheme_id, Ordering::SeqCst); inner.scheme_id.store(scheme_id, Ordering::SeqCst);
inner inner

View file

@ -12,12 +12,13 @@ use scheme::root::ROOT_SCHEME_ID;
use sync::{WaitQueue, WaitMap}; use sync::{WaitQueue, WaitMap};
use syscall::data::{Packet, Stat}; use syscall::data::{Packet, Stat};
use syscall::error::*; use syscall::error::*;
use syscall::flag::EVENT_READ; use syscall::flag::{EVENT_READ, O_NONBLOCK};
use syscall::number::*; use syscall::number::*;
use syscall::scheme::Scheme; use syscall::scheme::Scheme;
pub struct UserInner { pub struct UserInner {
handle_id: usize, handle_id: usize,
flags: usize,
pub scheme_id: AtomicUsize, pub scheme_id: AtomicUsize,
next_id: AtomicU64, next_id: AtomicU64,
context: Weak<RwLock<Context>>, context: Weak<RwLock<Context>>,
@ -26,9 +27,10 @@ pub struct UserInner {
} }
impl UserInner { impl UserInner {
pub fn new(handle_id: usize, context: Weak<RwLock<Context>>) -> UserInner { pub fn new(handle_id: usize, flags: usize, context: Weak<RwLock<Context>>) -> UserInner {
UserInner { UserInner {
handle_id: handle_id, handle_id: handle_id,
flags: flags,
scheme_id: AtomicUsize::new(0), scheme_id: AtomicUsize::new(0),
next_id: AtomicU64::new(1), next_id: AtomicU64::new(1),
context: context, context: context,
@ -158,7 +160,7 @@ impl UserInner {
pub fn read(&self, buf: &mut [u8]) -> Result<usize> { pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
let packet_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Packet, buf.len()/mem::size_of::<Packet>()) }; let packet_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Packet, buf.len()/mem::size_of::<Packet>()) };
Ok(self.todo.receive_into(packet_buf) * mem::size_of::<Packet>()) Ok(self.todo.receive_into(packet_buf, self.flags & O_NONBLOCK != O_NONBLOCK) * mem::size_of::<Packet>())
} }
pub fn write(&self, buf: &[u8]) -> Result<usize> { pub fn write(&self, buf: &[u8]) -> Result<usize> {

View file

@ -1,6 +1,4 @@
use collections::vec_deque::VecDeque; use collections::vec_deque::VecDeque;
use core::mem;
use core::ops::DerefMut;
use spin::Mutex; use spin::Mutex;
use sync::WaitCondition; use sync::WaitCondition;
@ -39,40 +37,29 @@ impl<T> WaitQueue<T> {
} }
} }
pub fn receive_into(&self, buf: &mut [T]) -> usize { pub fn receive_into(&self, buf: &mut [T], block: bool) -> usize {
let mut i = 0; let mut i = 0;
if i < buf.len() { if i < buf.len() && block {
buf[i] = self.receive(); buf[i] = self.receive();
i += 1; i += 1;
} }
{
let mut inner = self.inner.lock();
while i < buf.len() { while i < buf.len() {
if let Some(value) = self.inner.lock().pop_front() { if let Some(value) = inner.pop_front() {
buf[i] = value; buf[i] = value;
i += 1; i += 1;
} else { } else {
break; break;
} }
} }
}
i i
} }
pub fn receive_all(&self) -> VecDeque<T> {
loop {
{
let mut inner = self.inner.lock();
if ! inner.is_empty() {
let mut swap_inner = VecDeque::new();
mem::swap(inner.deref_mut(), &mut swap_inner);
return swap_inner;
}
}
self.condition.wait();
}
}
pub fn send(&self, value: T) -> usize { pub fn send(&self, value: T) -> usize {
let len = { let len = {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();