mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-02-02 09:46:06 +00:00
Remove unnecessary Option
from ZalsaLocal::query_stack
This commit is contained in:
parent
f65ac4b4c3
commit
ac40e4cf44
2 changed files with 91 additions and 111 deletions
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
mem,
|
||||
panic::panic_any,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
|
@ -198,18 +199,18 @@ impl Runtime {
|
|||
},
|
||||
});
|
||||
|
||||
let stack = local_state.take_query_stack();
|
||||
|
||||
let (stack, result) = DependencyGraph::block_on(
|
||||
let result = local_state.with_query_stack(|stack| {
|
||||
let (new_stack, result) = DependencyGraph::block_on(
|
||||
dg,
|
||||
thread_id,
|
||||
database_key,
|
||||
other_id,
|
||||
stack,
|
||||
mem::take(stack),
|
||||
query_mutex_guard,
|
||||
);
|
||||
|
||||
local_state.restore_query_stack(stack);
|
||||
*stack = new_stack;
|
||||
result
|
||||
});
|
||||
|
||||
match result {
|
||||
WaitResult::Completed => (),
|
||||
|
@ -244,7 +245,7 @@ impl Runtime {
|
|||
database_key_index
|
||||
);
|
||||
|
||||
let mut from_stack = local_state.take_query_stack();
|
||||
let (me_recovered, others_recovered, cycle) = local_state.with_query_stack(|from_stack| {
|
||||
let from_id = std::thread::current().id();
|
||||
|
||||
// Make a "dummy stack frame". As we iterate through the cycle, we will collect the
|
||||
|
@ -257,7 +258,7 @@ impl Runtime {
|
|||
let mut v = vec![];
|
||||
dg.for_each_cycle_participant(
|
||||
from_id,
|
||||
&mut from_stack,
|
||||
from_stack,
|
||||
database_key_index,
|
||||
to_id,
|
||||
|aqs| {
|
||||
|
@ -272,6 +273,7 @@ impl Runtime {
|
|||
// (at least for this execution, not necessarily across executions),
|
||||
// no matter where it started on the stack. Find the minimum
|
||||
// key and rotate it to the front.
|
||||
|
||||
if let Some((_, index, _)) = v
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
@ -294,7 +296,7 @@ impl Runtime {
|
|||
// Mark each cycle participant that has recovery set, along with
|
||||
// any frames that come after them on the same thread. Those frames
|
||||
// are going to be unwound so that fallback can occur.
|
||||
dg.for_each_cycle_participant(from_id, &mut from_stack, database_key_index, to_id, |aqs| {
|
||||
dg.for_each_cycle_participant(from_id, from_stack, database_key_index, to_id, |aqs| {
|
||||
aqs.iter_mut()
|
||||
.skip_while(|aq| {
|
||||
match db
|
||||
|
@ -318,9 +320,9 @@ impl Runtime {
|
|||
// They will throw the cycle, which will be caught by the frame that has
|
||||
// cycle recovery so that it can execute that recovery.
|
||||
let (me_recovered, others_recovered) =
|
||||
dg.maybe_unblock_runtimes_in_cycle(from_id, &from_stack, database_key_index, to_id);
|
||||
|
||||
local_state.restore_query_stack(from_stack);
|
||||
dg.maybe_unblock_runtimes_in_cycle(from_id, from_stack, database_key_index, to_id);
|
||||
(me_recovered, others_recovered, cycle)
|
||||
});
|
||||
|
||||
if me_recovered {
|
||||
// If the current thread has recovery, we want to throw
|
||||
|
|
|
@ -37,7 +37,7 @@ pub struct ZalsaLocal {
|
|||
///
|
||||
/// Unwinding note: pushes onto this vector must be popped -- even
|
||||
/// during unwinding.
|
||||
query_stack: RefCell<Option<Vec<ActiveQuery>>>,
|
||||
query_stack: RefCell<Vec<ActiveQuery>>,
|
||||
|
||||
/// Stores the most recent page for a given ingredient.
|
||||
/// This is thread-local to avoid contention.
|
||||
|
@ -47,7 +47,7 @@ pub struct ZalsaLocal {
|
|||
impl ZalsaLocal {
|
||||
pub(crate) fn new() -> Self {
|
||||
ZalsaLocal {
|
||||
query_stack: RefCell::new(Some(vec![])),
|
||||
query_stack: RefCell::new(vec![]),
|
||||
most_recent_pages: RefCell::new(FxHashMap::default()),
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,6 @@ impl ZalsaLocal {
|
|||
#[inline]
|
||||
pub(crate) fn push_query(&self, database_key_index: DatabaseKeyIndex) -> ActiveQueryGuard<'_> {
|
||||
let mut query_stack = self.query_stack.borrow_mut();
|
||||
let query_stack = query_stack.as_mut().expect("local stack taken");
|
||||
query_stack.push(ActiveQuery::new(database_key_index));
|
||||
ActiveQueryGuard {
|
||||
local_state: self,
|
||||
|
@ -97,12 +96,9 @@ impl ZalsaLocal {
|
|||
}
|
||||
}
|
||||
|
||||
fn with_query_stack<R>(&self, c: impl FnOnce(&mut Vec<ActiveQuery>) -> R) -> R {
|
||||
c(self
|
||||
.query_stack
|
||||
.borrow_mut()
|
||||
.as_mut()
|
||||
.expect("query stack taken"))
|
||||
/// Executes a closure within the context of the current active query stacks.
|
||||
pub(crate) fn with_query_stack<R>(&self, c: impl FnOnce(&mut Vec<ActiveQuery>) -> R) -> R {
|
||||
c(self.query_stack.borrow_mut().as_mut())
|
||||
}
|
||||
|
||||
fn query_in_progress(&self) -> bool {
|
||||
|
@ -233,24 +229,6 @@ impl ZalsaLocal {
|
|||
})
|
||||
}
|
||||
|
||||
/// Takes the query stack and returns it. This is used when
|
||||
/// the current thread is blocking. The stack must be restored
|
||||
/// with [`Self::restore_query_stack`] when the thread unblocks.
|
||||
pub(crate) fn take_query_stack(&self) -> Vec<ActiveQuery> {
|
||||
assert!(
|
||||
self.query_stack.borrow().is_some(),
|
||||
"query stack already taken"
|
||||
);
|
||||
self.query_stack.take().unwrap()
|
||||
}
|
||||
|
||||
/// Restores a query stack taken with [`Self::take_query_stack`] once
|
||||
/// the thread unblocks.
|
||||
pub(crate) fn restore_query_stack(&self, stack: Vec<ActiveQuery>) {
|
||||
assert!(self.query_stack.borrow().is_none(), "query stack not taken");
|
||||
self.query_stack.replace(Some(stack));
|
||||
}
|
||||
|
||||
/// Called when the active queries creates an index from the
|
||||
/// entity table with the index `entity_index`. Has the following effects:
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue