diff --git a/src/concurrency/thread.rs b/src/concurrency/thread.rs index 750167ca78..730c27d016 100644 --- a/src/concurrency/thread.rs +++ b/src/concurrency/thread.rs @@ -161,7 +161,6 @@ pub enum BlockReason { Eventfd, /// Blocked on unnamed_socket. UnnamedSocket, - } /// The state of a thread. diff --git a/src/provenance_gc.rs b/src/provenance_gc.rs index b3d715db9c..1f4539b5de 100644 --- a/src/provenance_gc.rs +++ b/src/provenance_gc.rs @@ -46,6 +46,12 @@ impl VisitProvenance for std::cell::RefCell { } } +impl VisitProvenance for std::vec::Vec { + fn visit_provenance(&self, _visit: &mut VisitWith<'_>) { + // TODO: this is just a temporary change to get Vec to work in unblock_thread, might remove later. + } +} + impl VisitProvenance for BorTag { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { visit(None, Some(*self)) diff --git a/src/shims/unix/unnamed_socket.rs b/src/shims/unix/unnamed_socket.rs index 7791027c20..f6bc1dfaec 100644 --- a/src/shims/unix/unnamed_socket.rs +++ b/src/shims/unix/unnamed_socket.rs @@ -127,7 +127,7 @@ impl FileDescription for AnonSocket { fn read<'tcx>( &self, - _self_ref: &FileDescriptionRef, + self_ref: &FileDescriptionRef, _communicate_allowed: bool, ptr: Pointer, len: usize, @@ -162,28 +162,30 @@ impl FileDescription for AnonSocket { } else { // TODO: move this to helper // Blocking socketpair with writer and empty buffer. - let peer_fd = self.peer_fd().upgrade().unwrap(); - bytes = bytes.clone(); + let peer_fd = self.peer_fd().clone(); + let dest = dest.clone(); + let weak_self_ref = self_ref.downgrade(); ecx.block_thread( BlockReason::UnnamedSocket, None, callback!( - @capture<'tcx> { - self_ref: FileDescriptionRef, - peer_fd: Option, - bytes: [u8], - ptr: Pointer, - dest: MPlaceTy<'tcx>, - } - @unblock = |this| { - // TODO: We might need to decide what to do if peer_fd is closed when read is blocked. - anonsocket_read(self_ref, peer_fd, &bytes, ptr, dest, ecx) - } - ), + @capture<'tcx> { + weak_self_ref: WeakFileDescriptionRef, + peer_fd: WeakFileDescriptionRef, + bytes: Vec, + ptr: Pointer, + dest: MPlaceTy<'tcx>, + } + @unblock = |this| { + // TODO: We might need to decide what to do if peer_fd is closed when read is blocked. + anonsocket_read(weak_self_ref, peer_fd, &mut bytes[..], ptr, &dest, this) + } + ), ); } } } + interp_ok(()) } fn write<'tcx>( @@ -265,13 +267,14 @@ fn anonsocket_write<'tcx>( /// Read from AnonSocket and return the number of bytes read. fn anonsocket_read<'tcx>( - self_ref: FileDescriptionRef, - peer_fd: Option, - bytes: &[u8], + self_ref: WeakFileDescriptionRef, + peer_fd: WeakFileDescriptionRef, + bytes: &mut [u8], ptr: Pointer, dest: &MPlaceTy<'tcx>, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx> { + let self_ref = self_ref.upgrade().unwrap(); // TODO: handle this later let anonsocket = self_ref.downcast::().unwrap(); let Some(readbuf) = &anonsocket.readbuf else { // FIXME: This should return EBADF, but there's no nice way to do that as there's no @@ -299,6 +302,7 @@ fn anonsocket_read<'tcx>( // don't know what that *certain number* is, we will provide a notification every time // a read is successful. This might result in our epoll emulation providing more // notifications than the real system. + let peer_fd = peer_fd.upgrade(); // TODO: handle unwrap if let Some(peer_fd) = peer_fd { ecx.check_and_update_readiness(&peer_fd)?; }