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


Reply via email to