From ba82ddcf379012f804f377958526bcb2912b617a Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 21 May 2020 12:14:53 -0700 Subject: [PATCH] borrow out of handles: change error name and describe behavior in comment --- crates/wiggle/src/borrow.rs | 16 +++++++++++++++- crates/wiggle/src/error.rs | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/wiggle/src/borrow.rs b/crates/wiggle/src/borrow.rs index 2519f44dae..83d96c3448 100644 --- a/crates/wiggle/src/borrow.rs +++ b/crates/wiggle/src/borrow.rs @@ -44,8 +44,17 @@ impl BorrowChecker { } #[derive(Debug)] +/// This is a pretty naive way to account for borrows. This datastructure +/// could be made a lot more efficient with some effort. struct InnerBorrowChecker { + /// Map from handle to region borrowed. A HashMap is probably not ideal + /// for this but it works. It would be more efficient if we could + /// check `is_borrowed` without an O(n) iteration, by organizing borrows + /// by an ordering of Region. borrows: HashMap, + /// Handle to give out for the next borrow. This is the bare minimum of + /// bookkeeping of free handles, and in a pathological case we could run + /// out, hence [`GuestError::BorrowCheckerOutOfHandles`] next_handle: BorrowHandle, } @@ -71,9 +80,14 @@ impl InnerBorrowChecker { self.next_handle = BorrowHandle(0); } let h = self.next_handle; + // Get the next handle. Since we don't recycle handles until all of + // them have been returned, there is a pathological case where a user + // may make a Very Large (usize::MAX) number of valid borrows and + // unborrows while always keeping at least one borrow outstanding, and + // we will run out of borrow handles. self.next_handle = BorrowHandle( h.0.checked_add(1) - .ok_or_else(|| GuestError::BorrowCheckerOOM)?, + .ok_or_else(|| GuestError::BorrowCheckerOutOfHandles)?, ); Ok(h) } diff --git a/crates/wiggle/src/error.rs b/crates/wiggle/src/error.rs index 558f0c380a..5cfab66675 100644 --- a/crates/wiggle/src/error.rs +++ b/crates/wiggle/src/error.rs @@ -15,8 +15,8 @@ pub enum GuestError { PtrNotAligned(Region, u32), #[error("Pointer already borrowed: {0:?}")] PtrBorrowed(Region), - #[error("Borrow checker out of memory")] - BorrowCheckerOOM, + #[error("Borrow checker out of handles")] + BorrowCheckerOutOfHandles, #[error("Slice length mismatch")] SliceLengthsDiffer, #[error("In func {funcname}:{location}:")]