Commit ef919f3d authored by Jeremy Soller's avatar Jeremy Soller

Implement EINTR for anything using wait_queue

parent 46a63256
......@@ -7,7 +7,7 @@ use context;
use scheme::{self, SchemeId};
use sync::WaitQueue;
use syscall::data::Event;
use syscall::error::{Error, Result, EBADF, ESRCH};
use syscall::error::{Error, Result, EBADF, EINTR, ESRCH};
int_like!(EventQueueId, AtomicEventQueueId, usize, AtomicUsize);
......@@ -25,7 +25,7 @@ impl EventQueue {
}
pub fn read(&self, events: &mut [Event]) -> Result<usize> {
Ok(self.queue.receive_into(events, true))
self.queue.receive_into(events, true).ok_or(Error::new(EINTR))
}
pub fn write(&self, events: &[Event]) -> Result<usize> {
......
......@@ -68,7 +68,9 @@ impl Scheme for DebugScheme {
*handles.get(&id).ok_or(Error::new(EBADF))?
};
Ok(INPUT.call_once(init_input).receive_into(buf, flags & O_NONBLOCK != O_NONBLOCK))
INPUT.call_once(init_input)
.receive_into(buf, flags & O_NONBLOCK != O_NONBLOCK)
.ok_or(Error::new(EINTR))
}
/// Write the `buffer` to the `file`
......
......@@ -168,7 +168,10 @@ impl UserInner {
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>()) };
Ok(self.todo.receive_into(packet_buf, self.flags & O_NONBLOCK != O_NONBLOCK) * mem::size_of::<Packet>())
self.todo
.receive_into(packet_buf, self.flags & O_NONBLOCK != O_NONBLOCK)
.map(|count| count * mem::size_of::<Packet>())
.ok_or(Error::new(EINTR))
}
pub fn write(&self, buf: &[u8]) -> Result<usize> {
......
......@@ -27,6 +27,7 @@ impl<K, V> WaitMap<K, V> where K: Clone + Ord {
if let Some(value) = self.receive_nonblock(key) {
return value;
}
//TODO: use false from wait condition to indicate EINTR
let _ = self.condition.wait();
}
}
......
......@@ -28,20 +28,22 @@ impl<T> WaitQueue<T> {
self.inner.lock().is_empty()
}
pub fn receive(&self) -> T {
pub fn receive(&self) -> Option<T> {
loop {
if let Some(value) = self.inner.lock().pop_front() {
return value;
return Some(value);
}
if ! self.condition.wait() {
return None;
}
let _ = self.condition.wait();
}
}
pub fn receive_into(&self, buf: &mut [T], block: bool) -> usize {
pub fn receive_into(&self, buf: &mut [T], block: bool) -> Option<usize> {
let mut i = 0;
if i < buf.len() && block {
buf[i] = self.receive();
buf[i] = self.receive()?;
i += 1;
}
......@@ -57,7 +59,7 @@ impl<T> WaitQueue<T> {
}
}
i
Some(i)
}
pub fn send(&self, value: T) -> usize {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment