Skip to content

Commit 81137dd

Browse files
committed
Add test for panic in nested cycle
1 parent 5813326 commit 81137dd

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

src/function/sync.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ impl<'me> ClaimGuard<'me> {
243243
fn release_panicking(&self) {
244244
let mut syncs = self.sync_table.syncs.lock();
245245
let state = syncs.remove(&self.key_index).expect("key claimed twice?");
246+
tracing::debug!(
247+
"Release claim on {:?} due to panic",
248+
self.database_key_index()
249+
);
246250

247251
self.release(state, WaitResult::Panicked);
248252
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Shuttle doesn't like panics inside of its runtime.
2+
#![cfg(not(feature = "shuttle"))]
3+
4+
//! Tests that salsa doesn't get stuck after a panic in a nested cycle function.
5+
6+
use crate::sync::thread;
7+
use crate::{Knobs, KnobsDatabase};
8+
use std::panic::catch_unwind;
9+
10+
use salsa::CycleRecoveryAction;
11+
12+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, salsa::Update)]
13+
struct CycleValue(u32);
14+
15+
const MIN: CycleValue = CycleValue(0);
16+
const MAX: CycleValue = CycleValue(3);
17+
18+
#[salsa::tracked(cycle_fn=cycle_fn, cycle_initial=initial)]
19+
fn query_a(db: &dyn KnobsDatabase) -> CycleValue {
20+
db.signal(1);
21+
query_b(db)
22+
}
23+
24+
#[salsa::tracked(cycle_fn=cycle_fn, cycle_initial=initial)]
25+
fn query_b(db: &dyn KnobsDatabase) -> CycleValue {
26+
let c_value = query_c(db);
27+
CycleValue(c_value.0 + 1).min(MAX)
28+
}
29+
30+
#[salsa::tracked(cycle_fn=cycle_fn, cycle_initial=initial)]
31+
fn query_c(db: &dyn KnobsDatabase) -> CycleValue {
32+
let d_value = query_d(db);
33+
34+
if d_value > CycleValue(0) {
35+
let _e_value = query_e(db);
36+
let _b = query_b(db);
37+
db.wait_for(2);
38+
db.signal(3);
39+
panic!("Dragons are real");
40+
} else {
41+
let a_value = query_a(db);
42+
CycleValue(d_value.0.max(a_value.0))
43+
}
44+
}
45+
46+
#[salsa::tracked(cycle_fn=cycle_fn, cycle_initial=initial)]
47+
fn query_d(db: &dyn KnobsDatabase) -> CycleValue {
48+
query_c(db)
49+
}
50+
51+
#[salsa::tracked(cycle_fn=cycle_fn, cycle_initial=initial)]
52+
fn query_e(db: &dyn KnobsDatabase) -> CycleValue {
53+
query_c(db)
54+
}
55+
56+
fn cycle_fn(
57+
_db: &dyn KnobsDatabase,
58+
_value: &CycleValue,
59+
_count: u32,
60+
) -> CycleRecoveryAction<CycleValue> {
61+
CycleRecoveryAction::Iterate
62+
}
63+
64+
fn initial(_db: &dyn KnobsDatabase) -> CycleValue {
65+
MIN
66+
}
67+
68+
#[test_log::test]
69+
fn the_test() {
70+
tracing::debug!("Starting new run");
71+
let db_t1 = Knobs::default();
72+
let db_t2 = db_t1.clone();
73+
let db_t3 = db_t1.clone();
74+
let db_t4 = db_t1.clone();
75+
76+
let t1 = thread::spawn(move || {
77+
let _span = tracing::debug_span!("t1", thread_id = ?thread::current().id()).entered();
78+
79+
let result = query_a(&db_t1);
80+
result
81+
});
82+
let t2 = thread::spawn(move || {
83+
let _span = tracing::debug_span!("t4", thread_id = ?thread::current().id()).entered();
84+
db_t4.wait_for(1);
85+
db_t4.signal(2);
86+
query_b(&db_t4)
87+
});
88+
let t3 = thread::spawn(move || {
89+
let _span = tracing::debug_span!("t2", thread_id = ?thread::current().id()).entered();
90+
db_t2.wait_for(1);
91+
query_d(&db_t2)
92+
});
93+
94+
let r_t1 = t1.join();
95+
let r_t2 = t2.join();
96+
let r_t3 = t3.join();
97+
98+
assert!(r_t1.is_err());
99+
assert!(r_t2.is_err());
100+
assert!(r_t3.is_err());
101+
102+
// Pulling the cycle again at a later point should still result in a panic.
103+
assert!(catch_unwind(|| query_d(&db_t3)).is_err());
104+
}

tests/parallel/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod cycle_ab_peeping_c;
99
mod cycle_nested_deep;
1010
mod cycle_nested_deep_conditional;
1111
mod cycle_nested_deep_conditional_changed;
12+
mod cycle_nested_deep_panic;
1213
mod cycle_nested_three_threads;
1314
mod cycle_nested_three_threads_changed;
1415
mod cycle_panic;

0 commit comments

Comments
 (0)