diff --git a/core/storage/pager.rs b/core/storage/pager.rs index 688d2a80a..9ed7b162d 100644 --- a/core/storage/pager.rs +++ b/core/storage/pager.rs @@ -511,9 +511,9 @@ pub struct Pager { /// Mutex for synchronizing database initialization to prevent race conditions init_lock: Arc>, /// The state of the current allocate page operation. - allocate_page_state: RefCell, + allocate_page_state: RwLock, /// The state of the current allocate page1 operation. - allocate_page1_state: RefCell, + allocate_page1_state: RwLock, /// Cache page_size and reserved_space at Pager init and reuse for subsequent /// `usable_space` calls. TODO: Invalidate reserved_space when we add the functionality /// to change it. @@ -594,9 +594,9 @@ impl Pager { init_lock: Arc>, ) -> Result { let allocate_page1_state = if !db_state.is_initialized() { - RefCell::new(AllocatePage1State::Start) + RwLock::new(AllocatePage1State::Start) } else { - RefCell::new(AllocatePage1State::Done) + RwLock::new(AllocatePage1State::Done) }; let now = io.now(); Ok(Self { @@ -623,7 +623,7 @@ impl Pager { page_size: Cell::new(None), reserved_space: Cell::new(None), free_page_state: RefCell::new(FreePageState::Start), - allocate_page_state: RefCell::new(AllocatePageState::Start), + allocate_page_state: RwLock::new(AllocatePageState::Start), max_page_count: Cell::new(DEFAULT_MAX_PAGE_COUNT), #[cfg(not(feature = "omit_autovacuum"))] ptrmap_get_state: RefCell::new(PtrMapGetState::Start), @@ -1923,7 +1923,7 @@ impl Pager { #[instrument(skip_all, level = Level::DEBUG)] pub fn allocate_page1(&self) -> Result> { - let state = self.allocate_page1_state.borrow().clone(); + let state = self.allocate_page1_state.read().clone(); match state { AllocatePage1State::Start => { tracing::trace!("allocate_page1(Start)"); @@ -1973,8 +1973,7 @@ impl Pager { ); let c = begin_write_btree_page(self, &page1)?; - self.allocate_page1_state - .replace(AllocatePage1State::Writing { page: page1 }); + *self.allocate_page1_state.write() = AllocatePage1State::Writing { page: page1 }; io_yield_one!(c); } AllocatePage1State::Writing { page } => { @@ -1986,7 +1985,7 @@ impl Pager { LimboError::InternalError(format!("Failed to insert page 1 into cache: {e:?}")) })?; self.db_state.set(DbState::Initialized); - self.allocate_page1_state.replace(AllocatePage1State::Done); + *self.allocate_page1_state.write() = AllocatePage1State::Done; Ok(IOResult::Done(page.clone())) } AllocatePage1State::Done => unreachable!("cannot try to allocate page 1 again"), @@ -1995,7 +1994,7 @@ impl Pager { pub fn allocating_page1(&self) -> bool { matches!( - *self.allocate_page1_state.borrow(), + *self.allocate_page1_state.read(), AllocatePage1State::Writing { .. } ) } @@ -2019,7 +2018,7 @@ impl Pager { let header = header_ref.borrow_mut(); loop { - let mut state = self.allocate_page_state.borrow_mut(); + let mut state = self.allocate_page_state.write(); tracing::debug!("allocate_page(state={:?})", state); match &mut *state { AllocatePageState::Start => { @@ -2284,7 +2283,7 @@ impl Pager { self.syncing.store(false, Ordering::SeqCst); self.commit_info.state.set(CommitState::PrepareWal); self.commit_info.time.set(self.io.now()); - self.allocate_page_state.replace(AllocatePageState::Start); + *self.allocate_page_state.write() = AllocatePageState::Start; self.free_page_state.replace(FreePageState::Start); #[cfg(not(feature = "omit_autovacuum"))] {