Add nonblocking root scheme
This commit is contained in:
parent
dd1c0ca01d
commit
8fd25ee318
|
@ -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`
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
while i < buf.len() {
|
{
|
||||||
if let Some(value) = self.inner.lock().pop_front() {
|
let mut inner = self.inner.lock();
|
||||||
buf[i] = value;
|
while i < buf.len() {
|
||||||
i += 1;
|
if let Some(value) = inner.pop_front() {
|
||||||
} else {
|
buf[i] = value;
|
||||||
break;
|
i += 1;
|
||||||
|
} else {
|
||||||
|
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();
|
||||||
|
|
Loading…
Reference in a new issue