From ef919f3d5216a12b6c80637ffd617db935dc4c96 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Dec 2018 08:02:00 -0700 Subject: [PATCH] Implement EINTR for anything using wait_queue --- src/event.rs | 4 ++-- src/scheme/debug.rs | 4 +++- src/scheme/user.rs | 5 ++++- src/sync/wait_map.rs | 1 + src/sync/wait_queue.rs | 14 ++++++++------ 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/event.rs b/src/event.rs index f7cef70..dbe908f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -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 { - 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 { diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs index 17e016f..4f1cec5 100644 --- a/src/scheme/debug.rs +++ b/src/scheme/debug.rs @@ -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` diff --git a/src/scheme/user.rs b/src/scheme/user.rs index f894d8e..eab5704 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -168,7 +168,10 @@ impl UserInner { pub fn read(&self, buf: &mut [u8]) -> Result { let packet_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Packet, buf.len()/mem::size_of::()) }; - Ok(self.todo.receive_into(packet_buf, self.flags & O_NONBLOCK != O_NONBLOCK) * mem::size_of::()) + self.todo + .receive_into(packet_buf, self.flags & O_NONBLOCK != O_NONBLOCK) + .map(|count| count * mem::size_of::()) + .ok_or(Error::new(EINTR)) } pub fn write(&self, buf: &[u8]) -> Result { diff --git a/src/sync/wait_map.rs b/src/sync/wait_map.rs index 45c692a..aedcef5 100644 --- a/src/sync/wait_map.rs +++ b/src/sync/wait_map.rs @@ -27,6 +27,7 @@ impl WaitMap 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(); } } diff --git a/src/sync/wait_queue.rs b/src/sync/wait_queue.rs index 384a125..766ce89 100644 --- a/src/sync/wait_queue.rs +++ b/src/sync/wait_queue.rs @@ -28,20 +28,22 @@ impl WaitQueue { self.inner.lock().is_empty() } - pub fn receive(&self) -> T { + pub fn receive(&self) -> Option { 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 { let mut i = 0; if i < buf.len() && block { - buf[i] = self.receive(); + buf[i] = self.receive()?; i += 1; } @@ -57,7 +59,7 @@ impl WaitQueue { } } - i + Some(i) } pub fn send(&self, value: T) -> usize {