From ef919f3d5216a12b6c80637ffd617db935dc4c96 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> 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 f7cef70a..dbe908f4 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<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> { diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs index 17e016fa..4f1cec5b 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 f894d8ea..eab5704c 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<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> { diff --git a/src/sync/wait_map.rs b/src/sync/wait_map.rs index 45c692af..aedcef50 100644 --- a/src/sync/wait_map.rs +++ b/src/sync/wait_map.rs @@ -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(); } } diff --git a/src/sync/wait_queue.rs b/src/sync/wait_queue.rs index 384a125b..766ce895 100644 --- a/src/sync/wait_queue.rs +++ b/src/sync/wait_queue.rs @@ -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 { -- GitLab