At present, BqlRefCell checks whether BQL is locked when it blocks BQL unlock (in bql_block_unlock).
But the such check should be done earlier - at the beginning of BqlRefCell borrowing. So convert BqlRefCell::borrow field from Cell<> to BqlCell<>, to guarantee BQL is locked from the beginning when someone is trying to borrow BqlRefCell. Signed-off-by: Zhao Liu <[email protected]> --- rust/bql/src/cell.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/rust/bql/src/cell.rs b/rust/bql/src/cell.rs index 8ade7db629cf..0a436f7eb431 100644 --- a/rust/bql/src/cell.rs +++ b/rust/bql/src/cell.rs @@ -141,8 +141,10 @@ //! Multiple immutable borrows are allowed via [`borrow`](BqlRefCell::borrow), //! or a single mutable borrow via [`borrow_mut`](BqlRefCell::borrow_mut). The //! thread will panic if these rules are violated or if the BQL is not held. +#[cfg(feature = "debug_cell")] +use std::cell::Cell; use std::{ - cell::{Cell, UnsafeCell}, + cell::UnsafeCell, cmp::Ordering, fmt, marker::PhantomData, @@ -377,7 +379,7 @@ pub struct BqlRefCell<T> { // for std::cell::BqlRefCell), so that we can use offset_of! on it. // UnsafeCell and repr(C) both prevent usage of niches. value: UnsafeCell<T>, - borrow: Cell<BorrowFlag>, + borrow: BqlCell<BorrowFlag>, // Stores the location of the earliest currently active borrow. // This gets updated whenever we go from having zero borrows // to having a single borrow. When a borrow occurs, this gets included @@ -426,7 +428,7 @@ impl<T> BqlRefCell<T> { pub const fn new(value: T) -> BqlRefCell<T> { BqlRefCell { value: UnsafeCell::new(value), - borrow: Cell::new(UNUSED), + borrow: BqlCell::new(UNUSED), #[cfg(feature = "debug_cell")] borrowed_at: Cell::new(None), } @@ -688,12 +690,12 @@ fn from(t: T) -> BqlRefCell<T> { } struct BorrowRef<'b> { - borrow: &'b Cell<BorrowFlag>, + borrow: &'b BqlCell<BorrowFlag>, } impl<'b> BorrowRef<'b> { #[inline] - fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> { + fn new(borrow: &'b BqlCell<BorrowFlag>) -> Option<BorrowRef<'b>> { let b = borrow.get().wrapping_add(1); if !is_reading(b) { // Incrementing borrow can result in a non-reading value (<= 0) in these cases: @@ -789,12 +791,12 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } struct BorrowRefMut<'b> { - borrow: &'b Cell<BorrowFlag>, + borrow: &'b BqlCell<BorrowFlag>, } impl<'b> BorrowRefMut<'b> { #[inline] - fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> { + fn new(borrow: &'b BqlCell<BorrowFlag>) -> Option<BorrowRefMut<'b>> { // There must currently be no existing references when borrow_mut() is // called, so we explicitly only allow going from UNUSED to UNUSED - 1. match borrow.get() { -- 2.34.1
