mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Merge commit 'ddf105b646
' into sync-from-ra
This commit is contained in:
parent
0816d49d83
commit
e41ab350d6
378 changed files with 14720 additions and 3111 deletions
69
crates/salsa/tests/parallel/parallel_cycle_none_recover.rs
Normal file
69
crates/salsa/tests/parallel/parallel_cycle_none_recover.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
//! Test a cycle where no queries recover that occurs across threads.
|
||||
//! See the `../cycles.rs` for a complete listing of cycle tests,
|
||||
//! both intra and cross thread.
|
||||
|
||||
use crate::setup::{Knobs, ParDatabaseImpl};
|
||||
use expect_test::expect;
|
||||
use salsa::ParallelDatabase;
|
||||
use test_log::test;
|
||||
|
||||
#[test]
|
||||
fn parallel_cycle_none_recover() {
|
||||
let db = ParDatabaseImpl::default();
|
||||
db.knobs().signal_on_will_block.set(3);
|
||||
|
||||
let thread_a = std::thread::spawn({
|
||||
let db = db.snapshot();
|
||||
move || db.a(-1)
|
||||
});
|
||||
|
||||
let thread_b = std::thread::spawn({
|
||||
let db = db.snapshot();
|
||||
move || db.b(-1)
|
||||
});
|
||||
|
||||
// We expect B to panic because it detects a cycle (it is the one that calls A, ultimately).
|
||||
// Right now, it panics with a string.
|
||||
let err_b = thread_b.join().unwrap_err();
|
||||
if let Some(c) = err_b.downcast_ref::<salsa::Cycle>() {
|
||||
expect![[r#"
|
||||
[
|
||||
"a(-1)",
|
||||
"b(-1)",
|
||||
]
|
||||
"#]]
|
||||
.assert_debug_eq(&c.unexpected_participants(&db));
|
||||
} else {
|
||||
panic!("b failed in an unexpected way: {:?}", err_b);
|
||||
}
|
||||
|
||||
// We expect A to propagate a panic, which causes us to use the sentinel
|
||||
// type `Canceled`.
|
||||
assert!(thread_a.join().unwrap_err().downcast_ref::<salsa::Cycle>().is_some());
|
||||
}
|
||||
|
||||
#[salsa::query_group(ParallelCycleNoneRecover)]
|
||||
pub(crate) trait TestDatabase: Knobs {
|
||||
fn a(&self, key: i32) -> i32;
|
||||
fn b(&self, key: i32) -> i32;
|
||||
}
|
||||
|
||||
fn a(db: &dyn TestDatabase, key: i32) -> i32 {
|
||||
// Wait to create the cycle until both threads have entered
|
||||
db.signal(1);
|
||||
db.wait_for(2);
|
||||
|
||||
db.b(key)
|
||||
}
|
||||
|
||||
fn b(db: &dyn TestDatabase, key: i32) -> i32 {
|
||||
// Wait to create the cycle until both threads have entered
|
||||
db.wait_for(1);
|
||||
db.signal(2);
|
||||
|
||||
// Wait for thread A to block on this thread
|
||||
db.wait_for(3);
|
||||
|
||||
// Now try to execute A
|
||||
db.a(key)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue