diff --git a/README.md b/README.md index dc409d72..d47f72a3 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ just run webserver To run Fix-on-Arca, run: ```sh -just fix addblob.fix +just fix eval addblob.fix ``` # License diff --git a/common/src/buddy.rs b/common/src/buddy.rs index cec5b170..fd31d6c0 100644 --- a/common/src/buddy.rs +++ b/common/src/buddy.rs @@ -622,7 +622,7 @@ impl BuddyAllocatorImpl { pub fn set_caching(&self, enable: bool) -> bool { if cfg!(feature = "cache") { self.caching - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| Some(enable)) + .try_update(Ordering::SeqCst, Ordering::SeqCst, |_| Some(enable)) .unwrap_or_else(|x| x) } else { false diff --git a/common/src/pipe/uni.rs b/common/src/pipe/uni.rs index 7282f082..02f9867e 100644 --- a/common/src/pipe/uni.rs +++ b/common/src/pipe/uni.rs @@ -133,17 +133,20 @@ pub struct Reader { impl Reader { pub fn read(&mut self, data: &mut [u8]) -> Result { unsafe { + // Drain any buffered bytes before reporting the writer's hangup, so a + // reader still sees data the writer sent immediately before closing + // (e.g. a Close-ack the peer wrote just before dropping its end). + if self.ring.as_ref().unwrap().can_read() { + let bytes = self.ring.as_ref().unwrap().readable_bytes(); + let len = core::cmp::min(data.len(), bytes.len()); + data[..len].copy_from_slice(&(&(*bytes))[..len]); + self.ring.as_mut().unwrap().read(len); + return Ok(len); + } if self.is_closed() { return Err(Error::Closed); } - if !self.ring.as_ref().unwrap().can_read() { - return Err(Error::WouldBlock); - } - let bytes = self.ring.as_ref().unwrap().readable_bytes(); - let len = core::cmp::min(data.len(), bytes.len()); - data[..len].copy_from_slice(&(&(*bytes))[..len]); - self.ring.as_mut().unwrap().read(len); - Ok(len) + Err(Error::WouldBlock) } } diff --git a/common/src/util/concurrent_trie.rs b/common/src/util/concurrent_trie.rs index afb8c67d..b4ee0969 100644 --- a/common/src/util/concurrent_trie.rs +++ b/common/src/util/concurrent_trie.rs @@ -38,7 +38,7 @@ impl SyncBox { unsafe { Some(Box::from_raw( self.ptr - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| { + .try_update(Ordering::SeqCst, Ordering::SeqCst, |old| { if old.is_null() { None } else { @@ -54,7 +54,7 @@ impl SyncBox { let ptr = Box::into_raw(value); unsafe { self.ptr - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| { + .try_update(Ordering::SeqCst, Ordering::SeqCst, |old| { if old.is_null() { Some(ptr) } else { diff --git a/vmm/src/comm.rs b/vmm/src/comm.rs index 860d1b1e..61172a54 100644 --- a/vmm/src/comm.rs +++ b/vmm/src/comm.rs @@ -99,6 +99,7 @@ pub fn file_thread(mut file: File, mut pipe: FilePipe) { Response::Offset(offset) } Request::Close => { + pipe.send(&Response::Ack); return; } }; @@ -120,6 +121,7 @@ pub fn listener_thread(listener: TcpListener, mut pipe: ListenerPipe) { Response::Pipe(decompose_pipe(p)) } Request::Close => { + pipe.send(&Response::Ack); return; } }; @@ -142,6 +144,7 @@ pub fn stream_thread(mut stream: TcpStream, mut pipe: StreamPipe) { Response::Length(len) } Request::Close => { + pipe.send(&Response::Ack); return; } };